Tuesday, August 9, 2011

Inheritance and Overriding in Maven

Maven provides a mechanism for a project to inherit project information from its parent project. Information that a project can inherit from its parent project include:
  • Dependencies under <dependencies>
  • Dependencies under <dependencyManagement>
  • Properties under <properties>
  • Plugin list and configurations
  • And so on …
 Of course, all inherited information can be overridden. For example, declaring a property named version in a project itself will override the same property inherited from its parent project.

Any Maven configuration may have property references, in the form of ${property-name}, in it. An interesting question is: when a property is overridden, are all other inherited configurations with ${the-property-name} in them effectively different between the child and the parent, depending on the value of that property for each of them?

The issue can be illustrated with an example. In this example, there are two sibling projects A and B, both have project P as their parent. In project P’s POM file, there is a property named development.team, and a configuration of the Maven jar plug-in as described in the following POM fragment:
...
<properties>
    ...
    <development.team>tiger</development.team>
    ...
</properties>
...
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>

        <configuration>
            <archive>
                ...
                <manifestEntries>
                    <development-team>${development.team}</ development-team >
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
<plugins>

The configuration of Maven jar plugin will let Maven to write an entry named development-team into the manifest file for the jar file built out of the project associated with the POM. The entry may look like:

Development-team: tiger

In our example, both project A and B are jar packaging project. Both project A and B inherited the property and plugin configuration from project P. Project A, however, overrides the property with the following POM fragment in its own POM:
<properties>
    <development.team>wolf</development.team>
</properties>

Here comes our question. What will shows up as development-team in the manifest files in the jar files built out of project A and B.  A reasonable expectation, in the spirit of Open-Close principle, is that it is wolf for A, and tiger for B. Is it the way of Maven? I searched Maven documents but could not find a specification in this aspect. So I did an experiment and found that Maven does work this way. 

2 comments:

Terence said...

Oy yeah.. this is the question im asking me googling around 2 hours now too.
No clear answer, seems that we have to try it!

inherited properties said...

It’s good as your other blog posts , thank you for putting up.