views:

1861

answers:

3

from maven documentation

pluginManagement: is an element that is seen along side plugins. Plugin Management contains plugin elements in much the same way, except that rather than configuring plugin information for this particular project build, it is intended to configure project builds that inherit from this one. However, this only configures plugins that are actually referenced within the plugins element in the children. The children have every right to override pluginManagement definitions.

Now : if I have this in my parent POM

  <build>
   <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <executions>
             Some stuff for the children
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

and I run mvn help:effective-pom on the parent project I get what I want, namely the plugins part directly under build (the one doing the work) remains empty.

Now if I do the following :

  <build>
   <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <executions>
             Some stuff for the children
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <inherited>true</inherited>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
</plugins>
  </build>

mvn help:effective-pom I get again just what I want, the plugins contains just what is declared and the pluginManagement section is ignored.

BUT changing with the following

  <build>
   <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <executions>
             Some stuff for the children
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
    <plugins>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
            <executions>
             some stuff for adults only
            </execution>
          </executions>
       </plugin>
    </plugins>
  </build>

and running mvn help:effective-pom the stuff from pluginManagement section is added on top of what is declared already. as such :

  <build>
   <pluginManagement>
     ...
   </pluginManagement>
    <plugins>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
              <executions>
                 Some stuff for the children
                </execution>
            <executions>
             some stuff for adults only
            </execution>
          </executions>
       </plugin>
    </plugins>
  </build>

Is there a way to exclude the part for children from the parent pom's section ? In effect what I want is for the pluginManagement to behave exactly as the documentation states, that is I want it to apply for children only but not for the project in which it is declared.

As a corrolary, is there a way I can override the parts from the pluginManagement by declaring the plugin in the normal build section of a project ? whatever I try I get that the section is added to executions but I cannot override one that exists already.

EDIT:

I never did find an acceptable solution for this and as such the issue remains open. Closest solution was offered below and is currently the accepted solution for this question until something better comes up. Right now there are three ways to achieve the desired result (modulate plugin behaviour depending on where in the inheritance hierarchy the current POM is):

1 - using profiles, it will work but you must beware that profiles are not inherited, which is somewhat counter intuitive. They are (if activated) applied to the POM where declared and then this generated POM is propagated down. As such the only way to activate the profile for child POM is specifically on the command line (least I did not find another way). Property, file and other means of activation fail to activate the POM because the trigger is not in the POM where the profile is declared.

2 - (this is what I ended up doing) Declare the plugin as not inherited in the parent and re-declare (copy-paste) the tidbit in every child where it is wanted. Not ideal but it is simple and it works.

3 - Split the aggregation nature and parent nature of the parent POM. Then since the part that only applies to the parent is in a different project it is now possible to use pluginManagement as firstly intended. However this means that a new artificial project must be created that does not contribute to the end product but only serves the could system. This is clear case of conceptual bleed. Also this only applies to my specific and is hard to generalize, so I abandoned efforts to try and make this work in favor of the not-pretty but more contained cut and paste patch described in 2.

If anyone coming across this question has a better solution either because of my lack of knowledge of Maven or because the tool evolved to allow this please post the solution here for future reference.

Thank you all for your help :-)

+3  A: 

Adding the plugin configuration to pluginManagement means that this configuration will be used if the plugin is declared, but you still need to declare the plugin in the build section of any POM that wants to use it.

The key part that explains this from the section you quoted is:

However, this only configures plugins that are actually referenced within the plugins element in the children

So if you do this in the child pom the configuration from the parent will be applied:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-dependency-plugin</artifactId>
    </plugin>
  </plugins>
</build>

Update: To answer the actual question, the content from the pluginManagement section is always merged with any plugin declaration. To avoid the parent doing this, you can define the pluginManagement section within a profile, and activate that profile on child projects but not the parent. The child projects would then have to declare that profile.

For example:

<profiles>
  <profile>
    <id>for-children</id>
    <build>
      <pluginManagement>
        <plugins>
          <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.0</version>
            <executions>
              <!--Some stuff for the children-->
            </executions>
          </plugin>
        </plugins>
      </pluginManagement>
    </build>  
  </profile>
</profiles>
<build>
  <plugins>
    <plugin>
      <artifactId>maven-dependency-plugin</artifactId>
        <version>2.0</version>
        <inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
          <!--some stuff for adults only-->
        </executions>
     </plugin>
  </plugins>
</build>
Rich Seller
For this to work I must activate the profile explicitly on the command line. Which means that for greatly simplifying a seldom edited file (pom.xml) I must somewhat complexify a very often used command. I have tried and turned the problem every which ways. I think the only solution is to separate the aggregation from the parent POM, which I was hesitant to do because it creates an artificial project that serves no real purpose other than structuring the build system.
Newtopian
I wouldn't worry about separating the parent and aggregator, the more projects you have the less similar they are likely to be as a whole, so the more likely you are to define sets of projects with different parents, orthogonal to the grouping you wish to build them in. There's no perfect answer. I think of it as the same issue as inheritance vs composition in OOP.
Rich Seller
A: 

You must assign an ID to the execution so maven knows which ones overwrite each other and which are independent.

Aaron Digulla
I have tried that, unfortunately I cannot remove an execution section with this method. Also, changing a value with the same ID simply overrides this single value, thus for this to work I would have to redeclare the whole section with values that divert the action, this defeats the purpose of centralizing this behaviour so I do not repeat myself.
Newtopian
A: 

I always used to think that a child POM can inherit a plugin definition from its parent's pluginManagement section and specify only the executions it wants to run from that plugin by referencing them by ID and binding the execution to a phase. As long as the parent definition is in pluginManagement (and not directly in plugins) and is not bound to a phase, only the specific execution (with ID) will be run in that phase.

From reading the above, and from my own current problem, it looks like that's not true: it looks like a child POM will inherit the entire configuration of the plugin, including all executions. In terms of executions, the only thing the child can do is to override specific values - it cannot pick which executions to run, and which not to.

Is this a bug? What's the use of being able to bind each execution to a phase (or not), if all executions will be run? I've only seen it with maven-dependency-plugin:unpack (bound to package phase), but with other plugins I might just have been lucky...

Damn.

Cornel Masson
Perhaps this sheds some light on the matter: http://maven.apache.org/guides/mini/guide-default-execution-ids.html. Looks like it might be fixed in Maven 2.2. Now if m2eclipse would only actually work with an external Maven installation...
Cornel Masson
hmmm... interesting, I will have to give that a try, though I am now in the hate part of the love hate relationship with Maven... again... Maven is great 90% of the time and does wonders... but the 10% that remains is just plain infuriating... it`s like having the absolute best and the absolute worst melded together where one is undiscernable from the other... arg ok n'uff said... back to POM again
Newtopian
@Newtopian, since my previous post I have logged a bug with Maven (see http://jira.codehaus.org/browse/MNG-4595), since it looks to me like a problem only with the maven-dependency-plugin.
Cornel Masson