Maven Building Multi-Module Engineering

Unless it is a simple project, most of the Maven projects encountered in practical work are multi-module. Each project module can be developed independently, and some of them may use the functions of other modules. How to use Maven to build a multi-module project?
Maven provides a way of inheritance and aggregation to build multi-module engineering, similar to the concept of inheritance and aggregation in Java.

Project Inheritance Structure

Project inheritance can reuse the content of pom files created in the parent project. The sub-project can automatically inherit the pom file attributes from the parent project.
For example, define the following attributes in the pom file of the parent project:

<groupId>com.packt.cookbook</groupId>
<artifactId>project-with-inheritance</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>

Then add the parent definition in the sub-project:

<parent>
    <groupId>com.packt.cookbook</groupId>
    <artifactId>project-with-inheritance</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>child</artifactId>
<packaging>jar</packaging>
<name>Child Project</name>

With the above definitions, we can use the properties and dependencies defined in the parent project's pom file in the sub-project.

NOTE:

  1. The parent project must be of type pom (packaging)
  2. The parent project is completely unaware of the existence of a child project, and only the parent element defined in the child project can specify the parent project.

Generally speaking, the parent project is in the parent directory of the sub-project. If the parent project is not in the parent directory of the sub-project, the sub-project will continue to look up in the maven warehouse for the parent project that meets the requirements. If you need to specify the location of the parent project yourself, you can add a new configuration of <relativePath>. / parent/pom.xml</relativePath>.

Modular aggregation structure

A parent project can have many sub-projects, and the parent project can not clearly know its sub-projects. The use of module aggregation can make the parent project clearly manage its sub-project, and the sub-project can become an independent existence without knowing the existence of its parent project.
How do I define modules in a parent project? Just define the modules element in the pom file of the parent project and create a new module configuration for each sub-module.

    <modules>
        <module>admin</module>
    </modules>

Although this management method is simple, it can not inherit the properties and dependencies defined in the parent project. Each sub-module must define its own dependencies and attributes independently, which does not exert the maximum power of maven project management.

Combining Inheritance with Aggregation

How to make maven project not only convenient for inheritance but also clear for aggregation? The answer is to combine these two features, using both inheritance and aggregation.
For example, let admin module inherit maven project, while Maven project uses modules element to explicitly manage admin module.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cc.adays</groupId>
    <artifactId>maven</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>cc.adays.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.9</version>
                <executions>
                    <execution>
                        <id>copy-dependency</id>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <modules>
        <module>admin</module>
    </modules>

</project>

parent elements are defined in the pom of admin sub-module.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>maven</artifactId>
        <groupId>cc.adays</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>admin</artifactId>

</project>

In this way, admin sub-elements can directly use dependencies and attributes defined in the parent project, while the parent project maven can clearly manage its sub-elements, killing two birds with one stone.

Dependency Management of Multimode Engineering

Finally, although inheritance is really good to use, sometimes sub-projects do not want to have all the dependencies of the parent project, how to do? At this point, dependency management must be relied on. It is very convenient to define dependency management in the parent project and then selectively use the dependencies already defined in the parent project in the sub-module.
Take a chestnut:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>

            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

There are two dependencies defined in the parent project, spring and Junit, but we only want to use JUnit in our sub-module, so in the pom file of the sub-module, we define:

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

Picture.png

There is no need to define version and scope here, as they are automatically inherited from the parent project.
In the same way, you can manage maven's plug-ins in this way. You only need to use the plugin management element. The specific way to use it is the same as the way to manage dependencies.

Keywords: Maven Apache Junit snapshot

Added by little_tris on Sun, 02 Jun 2019 20:57:24 +0300