10

In my project I alway use <dependency><dependency> but I can see <parent></parent> in some project pom.xml like:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.2.RELEASE</version>
</parent>

so I want to konw when to use it.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
jiangke
  • 305
  • 3
  • 13

4 Answers4

11

<parent> a superset of <dependencies>

<parent> and <dependencies> elements are two distinct things but it exists all the same an important relation between them.

Simply said the parent defines the parent pom of the current pom and dependencies defines the actual dependencies of the current pom.
The parent pom can define dependencies but also many other things inherited by the children Maven project (and particularly the dependencyManagement element and the build element that allow to configure many things) can so be considered in a some way as a superset of the dependencies element.
Here is the list of elements inherited from the parent pom :

groupId
version
description
url
inceptionYear
organization
licenses
developers
contributors
mailingLists
scm
issueManagement
ciManagement
properties
dependencyManagement
dependencies
repositories
pluginRepositories
build
plugin executions with matching ids
plugin configuration
etc.
reporting
profiles

As use dependencies and as use <parent>?

We can use only the first, only the second or both.
It depends really on the way which the Maven projects are designed.
Trying to enumerate all possible configurations would be long and not necessary very helpful.
So I think that you should really retain that parent is much more structuring as dependencies as it defines both more things for the children projects but it also allow not to repeat the actual configuration that you want to define in a set of projects.
So you should favor parent as you want to make inherit some child Maven projects an overall configuration and not only a list of dependencies.


Your example is perfect to illustrate the consequences on the client projects from using <parent> or dependencies as alternative.

1) With parent inheriting

Here the project inherits from the spring-boot-starter-parent pom :

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.2.RELEASE</version>
</parent>

As a consequence, the project will inherit any things defined in dependencies and dependencyManagement but it will also inherit from the <build> element defined in the super pom.

For example you would have the Maven compiler plugin configured out of the box with Java 8 and UTF-8 (that you can of course redefined in your child project) :

<properties>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <resource.delimiter>@</resource.delimiter>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

Additionally, some other plugins potential useful by a Spring Boot project will also be defined in the super pom and be inherited by your project such as :

<pluginManagement>
  <plugins>
     ...
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
            <execution>
                <goals>
                    <goal>repackage</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <mainClass>${start-class}</mainClass>
        </configuration>
    </plugin>
    ...
  </plugins>
</pluginManagement>

Note that a parent pom may define dependencies, directly inherited by the child projects but not necessary.
For example the spring-boot-starter-parent doesn't define any dependency directly inherited by child projects but instead of define dependency in <dependencyManagement><dependencies>.
It means that children of this parent pom may use the dependencies but they have to explicitly state that in dependencies.
For example :

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.2.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Note that the version is not valued as inherited.

2) Without parent inheriting

You will have to define all required dependencies by your Spring Boot application in or more straightly use the spring-boot-dependencies dependency in dependencyManagement with a import scope to have a way to declare them thanks to the dependency management feature :

<dependencyManagement>
        <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.2.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

But in any cases you will never inherit from the plugins configured out of the box by the parent as you don't have parent.
So you should declare them explicitly in the pom.xml of your project.

For example to define the compiler version, used encoding and configure the build to repackage the built component(to make it standalone executable), you will will have to specify more things :

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <springboot.version>1.5.2.RELEASE</springboot.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${springboot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
   <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
             <version>${springboot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>myClass</mainClass>
            </configuration>
        </plugin>      
   <plugins>
</build>
davidxxx
  • 125,838
  • 23
  • 214
  • 215
2

A parent POM can be declared with packaging pom. It is not meant to be distributed because it is only referenced from other projects.

Where as a dependency pom is declared as a jar. So, that it can be included in the project and thus the project can consume it's features.

Maven parent pom can contain almost everything and those can be inherited into child pom files, e.g

  • Common data – Developers’ names, SCM address, distribution management etc.
  • Constants – Such as version numbers
  • Common dependencies – Common to all child. It has same effect as writing them several times in individual pom files.
  • Properties – For example plugins, declarations, executions and IDs.
  • Configurations
  • Resources
Vinay
  • 76
  • 1
0

The use case <paraent> is where you store information for version(s) of artifacts and compiler settings/version which is used across modules.

See following for details Introduction to the POM

Jabir
  • 2,776
  • 1
  • 22
  • 31
0

A dependency is libraries you need to get your code to compile. This can be your own code, or libraries such as Apache Commons.

A parent contains information, but nothing to actually build, that is shared between a number of your projects. Suppose that you have a couple of modules of related code, and you want to ensure that the same versions of libraries are used by all modules. Then you could define those libraries in the <dependencies> section of each module, but you would define the version in the <dependencyManagement> section of the parent module.

Parent POMs can have their own parents, so you can build a whole hierarchy.

SeverityOne
  • 2,476
  • 12
  • 25