[Maven] [Translation] 1. POM.xml file

Keywords: Maven xml Java Apache

I. what is POM?

	POM is the abbreviation of Project Object Model and the basic unit of Maven's work; POM.xml is an XML file containing information and configuration details about Maven projects, which is used to build projects; it contains default values for most projects; for example, the target folder for building projects; for example, the resource folder- For example, [src/main/java]; for example, [src/test/java]; for example, when a task or target is executed, Maven looks for POM files in the current folder. Then read the information in POM, get the required configuration information, and then execute the target.
	Some special configurations in POM are Project Dependencies, where dependencies refer to jar packages that project depends on, some things like plug-ins or executable goals, build configurations, etc. Other information such as project versions, descriptions, developers, mailing lists, etc. can be specifically defined.

Super POM

Super POM is Maven's default POM, and all POM files inherit this super POM unless it is explicitly defined as non-inheritance; super POM files are inherited by other POM files you create, and the latest super POM file is 3.5.4; (you can understand as the base class, parent class of all POM files); here is an example.

<project>
  <modelVersion>4.0.0</modelVersion>
 
  <repositories>
    <repository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
 
  <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <updatePolicy>never</updatePolicy>
      </releases>
    </pluginRepository>
  </pluginRepositories>
 
  <build>
    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
    <pluginManagement>
      <!-- NOTE: These plugins will be removed from future versions of the super POM -->
      <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
      <plugins>
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.3</version>
        </plugin>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.8</version>
        </plugin>
        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
 
  <reporting>
    <outputDirectory>${project.build.directory}/site</outputDirectory>
  </reporting>
 
  <profiles>
    <!-- NOTE: The release profile will be removed from future versions of the super POM -->
    <profile>
      <id>release-profile</id>
 
      <activation>
        <property>
          <name>performRelease</name>
          <value>true</value>
        </property>
      </activation>
 
      <build>
        <plugins>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-source-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-sources</id>
                <goals>
                  <goal>jar-no-fork</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-javadoc-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-javadocs</id>
                <goals>
                  <goal>jar</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
              <updateReleaseInfo>true</updateReleaseInfo>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
 
</project>

The simplest POM

The cheapest POM file requires the following five parts:

  1. Project root directory;
  2. Module version - must be set to 4.0.0;
  3. Group ID - The group ID of the project;
  4. Product ID - ID of project product;
  5. Version - The version of a project product under a specific group;

Here's an example

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

A POM file will require you to configure your groupId,artifactId, and version number; these three values can fully define a product; in the form of <groupId>: <artifactId>: <version>; according to the example above, the complete product name of the above project is:

com.mycompany.app:my-app:1

Similarly, as mentioned in the first section, if configuration information is not explicitly defined, Maven uses default values. One of the default values is packaging type; each Maven project has a packaging type; if there is no explicit definition in POM, the default packaging type will be jar package;

In addition, you can see that repositories are not explicitly configured in the simplest POM files. If you use the simplest POM file to build a project, he will inherit the super POM repository configuration; therefore, when Maven sees the dependencies in the simplest POM file, he will go directly to the central repository to download (http://repo.maven.apache.org/maven2), which is the super POM configuration repository for all POM files;

IV. Project Inheritance

The elements in the POM file are merged as follows:

  1. Rely on jar package
  2. Developers and Contributors
  3. Plug-in list (including reports)
  4. Plug-in matching id;
  5. Plug-in configuration
  6. Resources

Super POM file is a classic example of project inheritance, but if you want to introduce your own parent POM file through the parent element in a specific POM, you are advised to see the following case demo:

4.1. Case 1
For example, let's reuse the previous product, com.mycompany.app:my-app:1, and let's introduce another product: com.mycompany.app:my-module:1;

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

Let's specifically define the file directory structure as follows:

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml

Note: my-module/pom.xml is the POM file of com.mycompany.app:my-module:1 product;
And pom.xml is the POM file of com.mycompany.app:my-app:1 product.

Solution
Now, if we set com.mycompany.app:my-app:1 as the parent project of com.mycompany.app:my-module:1, then we must modify the POM file of com.mycompany.app:my-module:1 as follows: (that is, we modify the POM file of the second subclass and add the information of the parent class)

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

Note that we added a label group section, which allows us to specify the product's parent information in the POM file; by defining the full qualified artifact name of its parent POM, our module can inherit its parent POM;

In addition, if we want our module's groupID or version to be the same as its parent class, we can remove groupId or version from the subclass module POM file.

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

4.2. Case II
However, in case 1 above, it must be that the parent project has been installed in our local warehouse or that the structure pom.xml parent pom.xml is a higher-level folder than your current module's pom.xml.
However, if the parent project is not installed or the folder structure is as follows:

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

Solution:
By adding folder structure addresses (or any other directory address), we can add the associated path < relativePath > to the parent section.

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

As the name suggests, the relative path of the module's pom.xml is the parent pom.xml

Project Aggregation

Item clustering is similar to project inheritance, but not in the module's parent POM file, but in the parent POM; through this operation, the parent project can know its sub-module, and if the Mavne command is invoked in the parent project, the Maven command can be executed in the parent module; in order to do module aggregation, you must do it. Do the following:

 1. Modify the value of the parent POMs package to pom (not jar)
 2. Catalogue of POM Neutron Modules Specially Defining Parent Classes

5.1. Case 3
The POMs and directory structure for an original product are given below.

com.mycompany.app:my-app:1's POM


POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

and

com.mycompany.app:my-module:1's POM

POM file

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

directory structure

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml

Solution
If we want to aggregate my-module into my-app module, we need to tightly modify the POM of my-app module:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>my-module</module>
  </modules>
</project>

In the revised com.mycompany.app:my-app:1 module, packaged group sections and module group sections are added; in order to package, his value is changed to "pom", and module group sections, we have elements: <module>my-module</module> module value is com.mycompany.app:my-app:1 relative to com.mycompany.app:my-modu: Relative path of le: 1's POM; (We used module catalog name of module products in particular);

Now, regardless of whether the Maven command handles com.mycompany.app:my-app:1, the same Maven command is executed simultaneously in com.mycompany.app:my-module:1; in addition, some commands (target specific definitions) are specially handled by the project;

5.2. Case IV
But what if we modify the directory as follows?

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

Will the POM of the parent class be specifically defined by the module?

Solution:
Answer? As in case 3, the relative path of the module is specifically defined:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>../my-module</module>
  </modules>
</project>

Yes.

  • [ ]

VI. Comparison of Project Inheritance and Project Aggregation

If you have several Maven projects and they all have similar configurations, you can reconstruct the project by adding parent projects and similar configuration files; all you have to do is let your Maven project inherit its parent projects and the configuration must be consistent with them;

Also, if you have a project team that you want to build or process at the same time, you can create a parent project and let the parent project define its subclasses; in this way, you need to build the parent project tightly, and the other subprojects will execute automatically without your worries;

But again, if you have both project inheritance and project dependency; note that you can specify a parent project and define the child project of the parent project; you must follow the following three rules:

 1. Define all of its sub-projects POM in the parent POM;
 2. Modify the packaging of POMs for parent projects to be pom
 3. Define the directory of the parent POM to the child project.

6.1. Case 5
Given the following original POMs product

com.mycompany.app:my-app:1's POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

com.mycompany.app:my-module:1's POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

The catalogue structure is as follows:

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

Solution
In order for both projects to be inherited and aggregated, you only need to follow the three items mentioned above.
com.mycompany.app:my-app:1's POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>../my-module</module>
  </modules>
</project>

com.mycompany.app:my-module:1's POM

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

Note: Configuration files inherit the same inheritance strategy;

Item Interpolation and Variables

One lesson Maven encourages is [don't repeat]; however, if you need to use the same variable many times in different places; to help variables be uniquely defined, Maven allows you to predefine your own variables in a POM file;

For example, to get the project.version variable, you can define it as follows:

 <version>${project.version}</version>

Note the fact that variables are processed after they are inherited, which means that if a parent project wants to use a variable, if the variable is defined in the child project instead of the parent project, the variables in the child project will be used finally;

Posted by common on Mon, 23 Sep 2019 03:52:41 -0700