Using Project Inheritance
One of the most powerful features in Maven is project inheritance. Using project inheritance allows you to do things like state your organizational information, state your deployment information, or state your common dependencies – all in a single place. Being the observant user, you have probably taken a peek at all the POMs in each of the projects that make up the Proficio project and noticed the following at the top of each of the POMs:
[...] <parent> <groupId>com.exist.mvnbook.proficio</groupId> <artifactId>proficio</artifactId> <version>1.0-SNAPSHOT</version> </parent> [...]
This is the snippet in each of the POMs that lets you draw on the resources stated in the specified top-level POM and from which you can inherit down to the level required – enabling you to add resources where it makes sense in the hierarchy of your projects. Let’s examine a case where it makes sense to put a resource in the top-level POM, using our top-level POM for the sample Proficio application.
If you look at the top-level POM for Proficio, you will see that in the dependencies section there is a declaration for JUnit version 3.8.1. In this case the assumption being made is that JUnit will be used for testing in all our child projects. So, by stating the dependency in the top-level POM once, you never have to declare this dependency again, in any of your child POMs. The dependency is stated as following:
<project> [...] <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> [...] </project>
What specifically happens for each child POM, is that each one inherits the dependencies section of the top-level POM. So, if you take a look at the POM for the
proficio-core module you will see the following (Note: There is no visible dependency declaration for JUnit):
<project> <parent> <groupId>com.exist.mvnbook.proficio</groupId> <artifactId>proficio</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>proficio-core</artifactId> <packaging>jar</packaging> <name>Maven Proficio Core</name> <dependencies> <dependency> <groupId>com.exist.mvnbook.proficio</groupId> <artifactId>proficio-api</artifactId> </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-container-default</artifactId> </dependency> </dependencies> </project>
In order for you to see what happens during the inheritance process, you will need to use the handy
mvn help:effective-pom command. This command will show you the final result for a target POM. After you move into the
proficio-core module directory and run the command, take a look at the resulting POM; you will see the JUnit version 3.8.1 dependency:
<project> [...] <dependencies> [...] <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> [...] </dependencies> [...] </project>
mvn help:effective-pomis bigger than you expected. But remember from Chapter 2 that the Super POM sits at the top of the inheritance hierarchy. So in this case, the
proficio-coreproject inherits from the top-level Proficio project, which in turn inherits from the Super POM. Looking at the effective POM includes everything and is useful to view when trying to figure out what is going on when you are having problems.