diff --git a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java index 181b29986e..c7daaf7b55 100644 --- a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java @@ -1728,6 +1728,33 @@ public class PomConstructionTest assertEquals( actual, expected ); } + /** MNG-4416 */ + public void testPluginOrderAfterMergingWithInjectedPlugins() + throws Exception + { + PomTestWrapper pom = buildPom( "plugin-injection-merge-order" ); + + List expected = new ArrayList(); + expected.add( "maven-it-plugin-error" ); + expected.add( "maven-it-plugin-configuration" ); + expected.add( "maven-it-plugin-dependency-resolution" ); + expected.add( "maven-it-plugin-packaging" ); + expected.add( "maven-it-plugin-log-file" ); + expected.add( "maven-it-plugin-expression" ); + expected.add( "maven-it-plugin-fork" ); + expected.add( "maven-it-plugin-touch" ); + + List actual = new ArrayList(); + for ( Plugin plugin : (List) pom.getValue( "build/plugins" ) ) + { + actual.add( plugin.getArtifactId() ); + } + + actual.retainAll( expected ); + + assertEquals( actual, expected ); + } + private void assertPathSuffixEquals( String expected, Object actual ) { String a = actual.toString(); diff --git a/maven-core/src/test/resources-project-builder/plugin-injection-merge-order/pom.xml b/maven-core/src/test/resources-project-builder/plugin-injection-merge-order/pom.xml new file mode 100644 index 0000000000..76459e2d53 --- /dev/null +++ b/maven-core/src/test/resources-project-builder/plugin-injection-merge-order/pom.xml @@ -0,0 +1,133 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng4416 + test + 0.1 + + Maven Integration Test :: MNG-4416 + + Test that merging of plugins during profile injection follows these rules regarding ordering: + model: X -> A -> B -> D -> E + profile: Y -> A -> C -> D -> F + result: X -> Y -> A -> B -> C -> D -> E -> F + + + + + + org.apache.maven.its.plugins + maven-it-plugin-error + 2.1-SNAPSHOT + + + org.apache.maven.its.plugins + maven-it-plugin-dependency-resolution + 2.1-SNAPSHOT + + + org.apache.maven.its.plugins + maven-it-plugin-packaging + 2.1-SNAPSHOT + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + org.apache.maven.its.plugins + maven-it-plugin-fork + 2.1-SNAPSHOT + + + + + + + test + + + !skip-mng4416 + + + + + + org.apache.maven.its.plugins + maven-it-plugin-configuration + 2.1-SNAPSHOT + + + org.apache.maven.its.plugins + maven-it-plugin-dependency-resolution + 2.1-SNAPSHOT + + + org.apache.maven.its.plugins + maven-it-plugin-log-file + 2.1-SNAPSHOT + + target/it.properties + + + + first + validate + + reset + + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + target/it.properties + + project/build/plugins + + + + + second + validate + + eval + + + + + + org.apache.maven.its.plugins + maven-it-plugin-touch + 2.1-SNAPSHOT + + + + + + diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java b/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java index 0a497d5195..7828632fe7 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java @@ -91,29 +91,49 @@ public class DefaultProfileInjector if ( !src.isEmpty() ) { List tgt = target.getPlugins(); - Map merged = new LinkedHashMap( ( src.size() + tgt.size() ) * 2 ); + Map master = new LinkedHashMap( tgt.size() * 2 ); for ( Plugin element : tgt ) { Object key = getPluginKey( element ); - merged.put( key, element ); + master.put( key, element ); } + Map> predecessors = new LinkedHashMap>(); + List pending = new ArrayList(); for ( Plugin element : src ) { Object key = getPluginKey( element ); - Plugin existing = merged.get( key ); - if ( existing == null ) + Plugin existing = master.get( key ); + if ( existing != null ) { - merged.put( key, element ); + mergePlugin( existing, element, sourceDominant, context ); + + if ( !pending.isEmpty() ) + { + predecessors.put( key, pending ); + pending = new ArrayList(); + } } else { - mergePlugin( existing, element, sourceDominant, context ); + pending.add( element ); } } - target.setPlugins( new ArrayList( merged.values() ) ); + List result = new ArrayList( src.size() + tgt.size() ); + for ( Map.Entry entry : master.entrySet() ) + { + List pre = predecessors.get( entry.getKey() ); + if ( pre != null ) + { + result.addAll( pre ); + } + result.add( entry.getValue() ); + } + result.addAll( pending ); + + target.setPlugins( result ); } }