3.5.2. Project Inheritance

There are going to be times when you want a project to inherit values from a parent POM. You might be building a large system, and you don't want to have to repeat the same dependency elements over and over again. You can avoid repeating yourself if your projects make use of inheritance via the parent element. When a project specifies a parent, it inherits the information in the parent project's POM. It can then override and add to the values specified in this parent POM.

All Maven POMs inherit values from a parent POM. If a POM does not specify a direct parent using the parent element, that POM will inherit values from the Super POM. Example 3.10, “Project Inheritance” shows the parent element of project-a which inherits the POM defined by the a-parent project.

Example 3.10. Project Inheritance

<project>
  <parent>
    <groupId>com.training.killerapp</groupId>
    <artifactId>a-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>project-a</artifactId>
  ...
</project>

Running mvn help:effective-pom in project-a would show a POM that is the result of merging the Super POM with the POM defined by a-parent and the POM defined in project-a. The implicit and explicit inheritance relationships for project-a are shown in Figure 3.3, “Project Inheritance for a-parent and project-a”.

Project Inheritance for a-parent and project-a

Figure 3.3. Project Inheritance for a-parent and project-a


When a project specifies a parent project, Maven uses that parent POM as a starting point before it reads the current project's POM. It inherits everything, including the groupId and version number. You'll notice that project-a does not specify either, both groupId and version are inherited from a-parent. With a parent element, all a POM really needs to define is an artifactId. This isn't mandatory, project-a could have a different groupId and version, but by not providing values, Maven will use the values specified in the parent POM. If you start using Maven to manage and build large multi-module projects, you will often be creating many projects which share a common groupId and version.

When you inherit a POM, you can choose to live with the inherited POM information or to selectively override it. The following is a list of items a Maven POM inherits from its parent POM:

  • identifiers (at least one of groupId or artifactId must be overridden.)

  • dependencies

  • developers and contributors

  • plugin lists

  • reports lists

  • plugin executions (executions with matching ids are merged)

  • plugin configuration

When Maven inherits dependencies, it will add dependencies of child projects to the dependencies defined in parent projects. You can use this feature of Maven to specify widely used dependencies across all projects which inherit from a top-level POM. For example, if your system makes universal use of the Log4J logging framework, you can list this dependency in your top-level POM. Any projects which inherit POM information from this project will automatically have Log4J as a dependency. Similarly, if you need to make sure that every project is using the same version of a Maven plugin, you can list this Maven plugin version explicitly in a top-level parent POM's pluginManagement section.

Maven assumes that the parent POM is available from the local repository, or available in the parent directory (../pom.xml) of the current project. If neither location is valid this default behavior may be overridden via the relativePath element. For example, some organizations prefer a flat project structure where a parent project's pom.xml isn't in the parent directory of a child project. It might be in a sibling directory to the project. If your child project were in a directory ./project-a and the parent project were in a directory named ./a-parent, you could specify the relative location of parent-a's POM with the following configuration:

<project>
  <parent>
    <groupId>org.sonatype.mavenbook</groupId>
    <artifactId>a-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../a-parent/pom.xml</relativePath>
  </parent>
  <artifactId>project-a</artifactId>
</project>