Maven pom.xml file details

POM stands for Project Object Model. It is an XML representation of a Maven project, stored in a file named pom.XML. A project contains not only a collection of files containing code, but also configuration files, as well as the roles of the developers involved and their roles, defect tracking systems, organizations and licenses, and where the project is located.URL s, project dependencies, and all the other bits of code that work to bring life to your code. In fact, in the Maven world, a project doesn't need to contain any code at all, it just needs one pom.xml.

Below is a list of elements in the pom.xml file. Note that the modelVersion must be 4.0.0. This is the only currently supported version of POM and is always required.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <!-- The Basics -->
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>...</version>
  <packaging>...</packaging>
  <dependencies>...</dependencies>
  <parent>...</parent>
  <dependencyManagement>...</dependencyManagement>
  <modules>...</modules>
  <properties>...</properties>
 
  <!-- Build Settings -->
  <build>...</build>
  <reporting>...</reporting>
 
  <!-- More Project Information -->
  <name>...</name>
  <description>...</description>
  <url>...</url>
  <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
  <organization>...</organization>
  <developers>...</developers>
  <contributors>...</contributors>
 
  <!-- Environment Settings -->
  <issueManagement>...</issueManagement>
  <ciManagement>...</ciManagement>
  <mailingLists>...</mailingLists>
  <scm>...</scm>
  <prerequisites>...</prerequisites>
  <repositories>...</repositories>
  <pluginRepositories>...</pluginRepositories>
  <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>
</project>

POM contains all the necessary information about the project and the plug-in configuration used during the build process. It is a declarative representation of "who", "what", and "where", while the build lifecycle is "when" and "how"This is not to say that POM does not affect the life cycle process - it can. For example, by configuring the maven-antrun-plugin plugin, Apache Ant tasks can be embedded in POM. However, this is ultimately a declaration. Although Ant's build.xml accurately tells Ant what to do at run time, POMDeclares its configuration. If some external forces cause the lifecycle to skip the execution of the Ant plug-in, it will not prevent the execution of other plug-ins. Unlike the build.xml file, tasks in the build.xml file almost always depend on the lines that precede them.

Maven coordinates

The POM defined above is the minimum allowed by Maven. Coordinate elements in Maven must contain groupId, artifactId, version. If groupId and version are inherited from their parent, no explicit definition is required.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>org.sonatype.nexus</groupId>
  <artifactId>nexus-indexer</artifactId>
  <version>2.0.0</version>
</project>
  • groupId: This element defines the actual project to which the current Maven project belongs and is usually unique within an actual project.

    First, Maven projects and actual projects are not necessarily one-to-one relationships. For example, Spring Framework, there are many Maven projects under it, such as spring-core, spring-context, etc. This is because of the concept of modules in Maven, a real project is often divided into many modules. groupId should not correspond to Maven.The organization or company to which the project belongs. The simple reason is that there are many actual projects under an organization or company. If groupld is defined only at the organizational or company level, then artifactld can only define the actual project level, then the Maven project level (module) level will be difficult to define.

    Second, groupId does not necessarily use a dot notation, such as the junit project. Note that a dot-based groupId does not have to correspond to the package structure contained in the project. However, this is a good practice to follow.

    Finally, groupld is represented in a similar way to Java package names, usually one-to-one correspondence with the inverted domain name. In the example above, groupld is org.sonatype.nexus, org.sonatype represents a non-profit organization established by Sonatype, and nexus represents the actual project Nexus, which is groupId versus the inverted nexus.sonatype.org Domain name correspondence. When stored in a warehouse, the dot number in groupId is replaced by an operating system-specific directory separator (such as /) that will become the relative directory structure under the warehouse base directory. For example, the org.sonatype.nexus group is located in the $M2_REPO/org/sonatype/nexus directory in the warehouse.

  • ArtifactId: This element defines a Maven project (module) in the actual project, and it is recommended that the actual project name be used as a prefix to the artifactId. For example, the artifactId in the above example is nexus-indexer.By default, Maven generates artifacts whose file names start with artifactId, such as nexus-indexer-2.0.0.jar, using the actual project name as a prefix, makes it easy to find a set of components for a project from a lib folder. Consider five projects, each project has a core module, and if there is no prefix, we will see many core-1.2.Files like jar, prefixed with the actual project name, make it easy to distinguish foo-core-1.2.jar, bar-core-1.2.jar, and so on. ArtifactId fully defines where artifacts are stored in the warehouse. The above items are located in the $M2_REPO/org/sonatype/nexus/nexus-indexer directory in the warehouse.

  • Version: This element defines the version in which the Maven project is currently located, as in the example above, the version of nexus-indexer is 2.0.0. It is important to note that Maven defines a set of completed version specifications, as well as a snapshot (SNAPSHOT)Version is also used to separate versions of an artifact in the warehouse, for example, the artifact for version 2.0.0 of the above project is located in the $M2_REPO/org/sonatype/nexus/nexus-indexer directory in the warehouse.

Now we have the address structure for groupId:artifactId:version, and a standard packaging element to define the packaging type for a Maven project. When no packaging type is declared, Maven assumes that the default packaging type is jar. The currently supported values for this element are: pom, jar, maven-plugin, ejb, war, ear, rar.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <packaging>war</packaging>
  ...
</project>

rely on

The cornerstone of POM is Dependency List Most projects rely on other projects to build and run properly. At compile time or when executing other targets that require these dependencies, Maven downloads and links them. As an added benefit, Maven introduces dependencies of these dependencies even if they are not explicitly declared., which allows your list to focus only on the dependencies required by the project.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <classifier>jar</classifier>
      <type>jar</type>
      <scope>test</scope>
      <systemPath>test</systemPath>
      <optional>true</optional>
    </dependency>
    ...
  </dependencies>
  ...
</project>
  • groupId, artifactId, version: These three elements are used to calculate the Maven coordinates of a particular project and treat them as dependencies of the project. Because of transitive dependencies, the same artifact can have multiple dependency declarations. Because dependencies are described by Maven coordinates, this means that the current project can only depend on MavenDependencies for managing artifacts and their dependencies. Unfortunately, sometimes projects cannot be downloaded from the Maven central repository. For example, a project may depend on a jar with a closed source license that does not allow it to be uploaded to the central repository. There are three ways to handle this situation.

    1. Use the install:install-file target of the maven-install-plugin plug-in to install a jar with a closed source license into a local repository. For example:

      mvn install:install-file -Dfile=D:\JavaDev\myapp.jar -DgroupId=com.myapp -DartifactId=myapp-core -Dversion=1.0.0 -Dpackaging=jar
      
    2. Use the deploy:deploy-file target of the maven-deploy-plugin plug-in to deploy the jar file with a closed source license to your private Maven repository. This way, development computers that can connect to the repository can use the dependency as they would normally.

    3. Set the dependency's scope subelement value to system and define a sibling systemPath subelement, then specify the value of the systemPath subelement as the local path to the jar file that has a closed source license. However, this is not recommended.

  • Classifier: This element is used to help define some satellite components for building output. It is an optional arbitrary string that, if present, is appended to the name of the artifact after the version number. If the main component in the above example is nexus-indexer-2.0.0.jar, the project may also be generated by using some plug-ins such asSome satellite components, such as nexus-indexer-2.0.0-javadoc.jar, nexus-indexer-2.0.0-sources.jar, contain Java documentation and source code. At this time, Javadoc and sources are classifiers for these two satellite components. Thus, the satellite has its own unique coordinates. Consider a project that provides a classifier for Java 11.The first artifact can specify a classifier value of jdk11, the second artifact can specify a classifier value of jdk8, so that the user can choose which one to use as needed. Note that you cannot directly define a classifier for a project.Because the satellite components are not generated directly by default by the project, they are generated with the help of additional plug-ins.

  • Type: Specifies the type of dependency selected, which in most cases does not need to be declared, defaulting to jar. Although it usually represents an extension on the dependency file name, this is not always the case: types can be mapped to different extensions and classifiers. Types are typically associated with packaging of dependenciesElement values correspond, although this is not always the case. New types can be defined by plug-ins that set extensions to true, so the list below is not a complete list. The artifact handler defines information (classifier, extension, language) for each dependency type on the artifact and how to manage it.Some artifact handlers are configured by default in META-INF/plexus/artifact-handlers.xml:

    typeclassifierextensionpackaginglanguageadded to classpathincludesDependencies
    pom= type= typenone
    jar= type= typejavatrue
    test-jartestsjarjarjavatrue
    maven-pluginjar= typejavatrue
    ejbjar= typejavatrue
    ejb-clientclientjarejbjavatrue
    war= type= typejavatrue
    ear= type= typejavatrue
    rar= type= typejavatrue
    java-sourcesourcesjar= typejava
    javadocjavadocjar= typejavatrue
  • Scope: This element specifies the scope of the dependency and how to limit its transitivity. Maven uses a set of compile class paths when compiling the main code of the project, and Maven uses a set of test class paths when compiling and executing tests. The runtime class paths are also used when actually running a Maven project. There are five available scopes:

    • Compile: This is the default scope used when no scope is specified. The scope dependencies are available in all class paths such as compile, test, runtime, and so on.
    • Provided: This scope is very similar to the compile scope, but it indicates that dependencies are available only on the compile and test class paths and not on the runtime class paths. Typically, a servlet-api dependency can be used when compiling and testing locally if the scope of the dependency is set to provided, but the runtime will choose to use itA servlet-api jar package in a Web container such as Tomcat or Jetty.
    • Runtime: This scope means that dependencies are available under test, runtime class paths, but not compile class paths. Typically, a JDBC-driven implementation requires only the JDBC interface provided by the JDK when the main code of the project is compiled, and only the driver implementation of the JDBC interface is used when the test is executed or the project is run.
    • Test: This range means that the dependency is only available under the test class path. Dependencies used as tests, such as Junit, TestNG, spring-boot-starter-test, are only needed when compiling test code and running tests.
    • system: This range is consistent with the provided range. Dependencies that use this range must be used with the systemPath element.
  • systemPath: This element value specifies the path to the local jar file. Use this element only if the scope element value is system, otherwise, if it is set, the build will fail. The path must be absolute, so it is recommended that you use property to specify a computer-specific path, for example, ${java.home}/lib. Maven does not go to the repository to check for the dependency, but rather ensures that the file exists based on the path of the element value. If it does not exist, Maven will fail the build and recommends that you manually download and install it.

  • Optional: Mark dependencies as optional when the project itself is a dependency. For example, if project A relies on project B to compile parts of code that may not be used at runtime, then we may not need to use project B for all projects. So if project X adds project A as its own dependency, then Maven Project B does not need to be installed at all. If symbolized, if=>indicates a required dependency, -->indicates an optional dependency, although project A may be built in A=>B, and project X in X=>A-->B optional.Scope lets other projects know that when you use the dependency, you don't necessarily need it to work properly.

Dependency Resolution Rules

Maven Intriguing transitive dependency mechanisms, on the one hand, greatly simplify and facilitate the declaration of dependency, on the other hand, in most cases we only need to care about what the direct dependencies of the project are, regardless of what they lead to. But sometimes, when transitive dependencies cause problems, we need to know exactly where they come from.Introduced by a dependent path.

For example, Project A has such a dependency: A->B->C->X(1.0), A->D->X(2.0). X is a transitive dependency of A, but there are two versions of X on the two dependency paths, so which X will be used by Maven parsing? It is obviously incorrect for both versions to be parsed, because that causes duplicate dependencies, so one must be selected. Mavency Dependency Mediation The first principle is that the nearest path takes precedence. In this case, the path length of X(1.0) is 3, and X(2.0) is 2, so X(2.0) is parsed and used.

Dependency on the first principle of mediation does not solve all problems, such as dependencies such as A->B->Y(1.0), A->C->Y(2.0), Y(1.0) and Y(2.0) which have the same length of dependent paths, all of which are 2. So who will be resolved and used?In versions 8 and earlier, this was uncertain, but from Maven2.Beginning with 0.9, in order to avoid as much uncertainty as possible in construction, Maven defined the second principle of relying on mediation: first declarator takes precedence. With equal path lengths, the order of dependent declarations in the POM determines who will be resolved and the top dependency wins. In this case, if B's dependency declaration precedes C, then Y (1.0)Will be parsed for use.

You can use some of the goals of maven-dependency-plugin to help you view the dependencies of a project:

  • The mvn dependency:list command lists the resolved explicit declared dependencies, excluding indirect dependencies.
  • The mvn dependency:tree command lists the dependencies that are actually in effect.
  • The mvn dependency:analyze command analyzes the dependencies of this project and determines which are explicitly declared and used, which are not explicitly declared but used, and which are explicitly declared but not used.

Dependent Version Specification

The version element of a dependency defines a version requirement used to calculate the version of the dependency. Soft Requirement s can be replaced by different versions of the same artifact in the dependency diagram. Hard Requirement sRequires a specific version or versions and overrides the soft requirements. Build fails if there are no dependency versions that meet all the hard requirements of the current project.

Version requirements have the following syntax:

  • Soft requirements of 1.0:1.0. Use 1.0 if no other version has previously appeared in the dependency tree.
  • [1.0]:Hard requirements for 1.0. Use 1.0 and only 1.0.
  • (, 1.0]: Hard requirements for any version <=1.0.
  • [1.2,1.3]:Hard requirements for any version between 1.2 and 1.3 (including versions 1.2 and 1.3).
  • [1.0,2.0):1.0 <=x< 2.0, hard requirements for any version between version 1.0 (inclusive) and version 2.0 (excluded).
  • [1.5,]: Hard requirements for any version greater than or equal to 1.5.
  • (, 1.0], [1.2,]): Any hard requirement less than or equal to 1.0, greater than or equal to 1.2, but not equal to 1.1. Multiple requirements are separated by commas.
  • (, 1.1), (1.1,): Hard requirements for any version other than 1.1; for example, because 1.1 has a serious vulnerability.

Maven chooses the highest version of a dependency that meets all the hard needs of the current project. If there is no version that meets all the hard needs, the build will fail.

Version Order Specification

If the version string is syntactically correct Semantic Version 1.0.0 Specification Version comparison follows the precedence rules outlined in the specification in almost all cases. These versions are common alphanumeric ASCII strings, such as 2.15.2-alpha. More precisely, if the two version numbers to be compared match the valid semver product in the BNF syntax in the semantic version control specification, this is correct.Any semantics implied by the specification.

Important note: This applies only to the Semantic Version 1.0.0 specification. The Maven Version Sequencing algorithm is incompatible with the Semantic Version 2.0.0 standard. In particular, Maven does not make special handling of plus signs and does not consider building identifiers. When version strings do not follow the Semantic Version Control, a more complex set of rules is required. Maven uses dots (.) and hyphens (-).Separate coordinates by markers, number-to-letter conversions. Points (.) and hyphens (-) are recorded as separators and will affect order. Conversions between numbers and subtitles are equivalent to hyphens, and empty markers between consecutive separators are replaced with 0. This will provide a series of bands with.The version number of the or-prefix (numeric tag) and the version qualifier (non-numeric tag). Example of split and replace: 1-1.foo-bar1baz-.1 -> 1-1.foo-bar-1-baz-0.1.

Then, starting at the end of the version, the null values at the end (0, ""","final","ga") will be removed. This process is repeated from beginning to end at each remaining hyphen. Excision example:

  • 1.0.0 -> 1
  • 1.ga -> 1
  • 1.final -> 1
  • 1.0 -> 1
  • 1. -> 1
  • 1- -> 1
  • 1.0.0-foo.0.0 -> 1-foo
  • 1.0.0-0.0.0 -> 1

The version order is the lexicographical order of the prefix tag sequence, where a shorter tag fills in enough null values and has a matching prefix of the same length as a longer tag. Filling null values depends on the prefix of another version: 0 for., and - for.. The prefixed tag order is:

  • If the prefixes are the same, the comparison tags:

    • Numeric markers have a natural order.

    • Non-numeric tags ("qualifiers") are arranged alphabetically, but the following tags are first in alphabetical order: "alpha"<"beta"<"milestone"<"rc"="cr"<"snapshot"<"="final"="ga"<"sp"

      • The qualifiers "alpha", "beta" and "milestone" can be shortened to a, b, and m, respectively, when followed directly by a number.
  • Or:'.qualifier'<'-qualifier' <'-number'<'.number'.

Examples of final results:

  • "1" < "1.1" (Number Fill)
  • "1-snapshot" < "1" < "1-sp" (qualifier fill)
  • "1-foo2" < "1-foo10" (correctly automatically "switch" to numeric order)
  • "1.foo" < "1-foo" < "1-1" < "1.1"
  • "1.ga"="1-ga"="1-0"="1.0"="1" (removes the null value at the end)
  • "1-sp" > "1-ga"
  • "1-sp.1" > "1-ga.1"
  • "1-sp-1" < "1-ga-1" = "1-1" (removes the null value at the hyphen)
  • "1-a1" = "1-alpha-1"

Note: Contrary to some design documents, snapshot is handled in the same way as release or any other qualifier for version order.

Version Order Test

The Maven distribution includes a tool to compare the order between specified versions. If in doubt, run it yourself. You can run it like this:

java -jar ${MAVEN_HOME}/lib/maven-artifact-3.3.9.jar [versions...]

Example

$ java -jar ./lib/maven-artifact-3.3.9.jar  1 2 1.1
Display parameters as parsed by Maven (in canonical form) and comparison result:
1. 1 == 1
   1 < 2
2. 2 == 2
   2 > 1.1
3. 1.1 == 1.1

Dependency Exclusion

The exclusion element allows Maven to exclude certain indirect dependencies of a dependency when it contains it (in other words, its transitive dependencies). The exclusions element can contain one or more exclusion elements, each containing a groupId and an artifactId, indicating the dependency to be excluded.For example, maven-embedder is indirectly dependent on maven-core, and we do not want to use it or its dependencies, so we explicitly place the groupId and artifact of maven-core in the exclusion element.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-embedder</artifactId>
      <version>2.0</version>
      <exclusions>
        <exclusion>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    ...
  </dependencies>
  ...
</project>

If the scope of a dependency may be absent, the current version has security holes, or conflicts with other dependencies in the project, it may be necessary to remove the transitive dependencies of a dependency. Using wildcard exclusion makes it easy to exclude all transitive dependencies of a dependency. In the following cases, you may be using maven-embedder and you want to manage it yourselfDependencies used, so you can trim all transitive dependencies:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-embedder</artifactId>
      <version>3.1.0</version>
      <exclusions>
        <exclusion>
          <groupId>*</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    ...
  </dependencies>
  ...
</project>

inherit

A powerful addition to Maven's build management is the concept of project inheritance. Build systems such as Ant can simulate inheritance, but Maven has explicitly declared it in the project object model.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>my-parent</artifactId>
  <version>2.0</version>
  <packaging>pom</packaging>
</project>

For a parent project, the value of the packaging element in its pom.xml must be of type pom. The packaging element value is bound to a set of life cycle phase goals. For example, if the package is jar, then the package phase will execute the jar:jar target. Most elements in the parent POM can be inherited by its children POM, including:

  • 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

Elements not inherited include:

  • artifactId
  • name
  • prerequisites

An example of a sub-POM is as follows:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <parent>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>my-parent</artifactId>
    <version>2.0</version>
    <relativePath>../my-parent</relativePath>
  </parent>
 
  <artifactId>my-project</artifactId>
</project>

Note that the relativePath element is not required, but can be used as a flag of Maven to search the path of the parent project of the project specified by the value of the relativePath element before searching for local and remote warehouses.

Super POM

Similar to object inheritance in object-oriented programming, POM that extends the parent POM inherits certain values from the parent POM. In addition, just as Java objects ultimately inherit from java.lang.Object, all project object models inherit from a basic Super POM. The following code snippet is Maven 3.5.4 Super POM.

<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>

By creating a minimum pom.xml and executing it on the command line: mvn help:effective-pom, you can understand how Super POM affects the project object model.

Dependency Management

In addition to inheriting certain top-level elements, the <dependencyManagement>element in the parent POM can help manage dependency information for all its child POMs. Dependency details declared in the <dependencyManagement>element in the parent POM are inherited by the child POM if the child POM is in its <dependecies>Some dependency configurations, such as version, scope, can be omitted if the same dependency is declared in the element. Although the <dependencyManagement>element of the parent POM sets the details of a dependency, if the corresponding groupId and artifactId are not used in the child POM to explicitly use the inherited dependency, then the child POMThis dependency will not be used. Of course, sub-POMs can also override inherited dependency configurations using different dependency configurations depending on their own circumstances.

For example, if my-parent project defines a dependency on junit:junit:4.12 in its dependency management element, then the child POM inherited from this project only needs to provide groupId=junit and artifactId=junit to use this dependency declared in the parent POM, and Maven will automatically populate the JUnit set in the parent POMDependency version. The benefits of this approach are obvious. Dependency details can be configured in a central location, and these configurations will be propagated to all child POMs.

polymerization

Projects that declare multiple modules through the <modules>element are called aggregated projects (or multimodule projects)The <packaging>element value of an aggregated project must also be a pom. <modules>element's subelement <module>specifies the relative path of a submodule to the aggregated project. Generally, the submodule project of an aggregated project exists as a subdirectory under the aggregated project root directory, but it is not absolute.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>my-parent</artifactId>
  <version>2.0</version>
  <packaging>pom</packaging>
 
  <modules>
    <!-- Put the sub-module project of the aggregate project under the aggregate project root directory as a sub-directory -->
    <module>my-project</module>
    <!-- The sub-module project directory of an aggregated project is the same level as the aggregated project directory -->
    <module>../another-project</module>
  </modules>
</project>

When listing modules, you do not need to consider the order in which they are declared, even if there are dependencies between the modules. Maven topologically sorts the modules so that the dependent modules are always built before the dependent modules. However, no circular dependencies can occur between the modules, or Maven will fail.

Inherit VS Aggregation

Inheritance and aggregation create a good dynamic control over construction through a single advanced pom. The <packaging>element values of both parent and aggregated items are poms, and both contain nothing but pom. It is common to see that an item is both a parent and an aggregated item, but inheritance and aggregation are not a concept. The differences between the two are as follows:

  • The primary purpose of a parent project is to eliminate duplicate configurations. A parent project's pom.xml may contain no modules and be inherited solely as a parent project by its children through the <parent>element, in which case the parent project is only the parent project, not an aggregate project. The parent project does not know which children inherit it, and the children know which parent project it inherits.
  • The purpose of aggregating projects is to facilitate the management of multiple modules. The pom.xml of aggregating projects can contain several sub-modules, which can be grouped into a group to manage these sub-modules uniformly, such as clean, compile All sub-modules. Sub-modules do not require special declarations. Aggregation projects know which modules they aggregate, but sub-modules do not know who aggregated themselves and with whom they were aggregated.

property

Maven's property is a value placeholder, just like property in Ant. Their values can be accessed anywhere in the POM using the symbol ${X}, where X is property. Or they can be used as default values by plug-ins, such as:

<project>
  ...
  <properties>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <!-- Following project.-properties are reserved for Maven in will become elements in a future POM definition. -->
    <!-- Don't start your own properties properties with project. -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>
  ...
</project>

Property has five different styles:

  • env.X: Prefix the variable with env.A shell's environment variable will be returned. For example, ${env.PATH} contains the PATH environment variable. Although the environment variable itself is not case sensitive on Windows, property lookups are case sensitive. In other words, while the Windows shell returns the same value for%PATH% and%Path%, Maven distinguishes between ${env.PATH} and ${env.Path}For reliability, the name of the environment variable is normalized to all capitals.
  • project.x:The path represented by a dot (.) in the POM will contain the value of the corresponding element. For example: <project><version>1.0</version></project>can be accessed through ${project.version}.
  • The path in settings.x:settings.xml, denoted by a dot (.), will contain the value of the corresponding element. For example: <settings><offline>false</offline></settings>is accessible through ${settings.offline}.
  • Java System Properties: All properties accessed through java.lang.System.getProperties() can be used as POM properties, such as ${java.home}.
  • x: Set within the <properties/> element in the POM. <properties><someVar>value</someVar></properties>value can be used as ${someVar}.

Build Setting

structure

According to POM 4.0.0 XSD, <build>elements are conceptually divided into two parts, corresponding to a BaseBuild type, which contains a set of elements common to two <build>elements: <project>elements and top-level <build>elements under <profiles>elements; and a Build type that contains BaseBuildCollection and more elements defined at the top level. Let's start by analyzing the similarities between the two. Note: These different <build>elements can be represented as project build s and profile build s.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <!-- "Project Build" contains more elements than just the BaseBuild set -->
  <build>...</build>
 
  <profiles>
    <profile>
      <!-- "Profile Build" contains a subset of "Project Build"s elements -->
      <build>...</build>
    </profile>
  </profiles>
</project>

Infrastructure Elements

The BaseBuild type is, as it sounds, a collection of hierarchical child element elements from two <build>elements in the POM.

<build>
  <defaultGoal>install</defaultGoal>
  <directory>${basedir}/target</directory>
  <finalName>${artifactId}-${version}</finalName>
  <filters>
    <filter>filters/filter1.properties</filter>
  </filters>
  ...
</build>
  • defaultGoal: The default target or stage to execute when no target or stage is given. If a target is given, it should be defined on the command line (for example, jar:jar). This is also true if a stage (for example, install) is defined.
  • Directory: The target directory for the build output. It defaults to ${basedir}/target.
  • FinalName: This is the name of the project when the project is finally built (no file extension, for example, my-project-1.0.jar). It defaults to ${artifactId}-${version}. However, the term finalName is a bit inappropriate because the plug-in that built the project has full authority to ignore/modify this name (but usually does not)For example, if the maven-jar-plugin plug-in is configured to give jar a test classifier, the actual jar defined above will be built as my-project-1.0-test.jar.
  • Filter: Specify a *.properties file in which the name=value pair defined will be used to replace the ${name} string in the resource when it is built. The example above defines the filter1.properties file in the filters/directory. Maven's default filter directory is ${basedir}/src/main/filters/.

Resources

Another feature of the <build>element is to specify the location of resources in the project. Resources are usually not code, they do not compile, but are bundled in the project or used for a variety of other purposes (such as code generation, configuration files for the project). For example, Plexus projects require a configuration.xml file to be stored in the META-INF/plexus directory(Specify the component configuration for the container). Although we can place this file in src/main/resources/META-INF/plexus as easily as possible, we want to provide Plexus with its own directory, src/main/plexus. For the JAR plug-in to bind resources correctly, you can specify resources similar to the following:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <build>
    ...
	<resources>
   		<!-- Specify the directory where the resources used in the module are located -->
		<resource>
        	<!-- The default resource directory is src/main/resources -->
        	<directory>src/main/resources</directory>
            <!-- filtering Set to true Will be used in resource files of type text ${name}The attribute value represented is replaced by the corresponding attribute value (these attributes can be declared in five ways,
			Reference About Property Description -->
       		<filtering>true</filtering>
        	<!-- Specify the resource file you want to output (text files can be replaced with attribute references) -->
            <!-- No Output src/main/resources All under Catalog.properties and.xml resource file -->
        	<includes>
         		<include>**/*.properties</include> <!-- Output all txt resource files in the src/main/resources directory-->
          		<include>**/*.xml</include> <!-- output src/main/resources All under Catalog xml resource file -->
     		</includes>
    		<!-- Specifies that the output resource file is not required (binaries cannot be replaced with attribute references, otherwise the binary may be corrupted) -->
            <!-- No Output src/main/resources All under Catalog.bmp and.jpg resource file -->
        	<excludes>
           		<exclude>**/*.bmp</exclude> 
         		<exclude>**/*.jpg</exclude>
     		</excludes>
   		</resource>
        <!-- You can use multiple resource Element to specify multiple resource directories -->
      	<resource>
    		<directory>src/main/resources-filtered</directory>
         	<!-- includes and excludes Can be used in combination. The following configuration outputs all the items in the resource directory txt File but with the exception of the name test Of txt Outside of file -->
        	<includes>
         		<include>**/*.txt</include>
            </includes>
            <excludes>
               	<exclude>**/*test*.*</exclude>
            </excludes>
 		</resource>
	</resources>
    <testResources>
     	<testResource>
        	<!-- ... -->
      	</testResource>
 	</testResources>
    ...
  </build>
</project>
  • <resources>: is a list of <resource>elements, each of which is used to select which resource files will be copied to the class path of the build output, and the property references in the text class resource file may be replaced before the copy operation is performed.
  • <targetPath>: The directory where resources are built. The target path defaults to the base directory. META-INF target directories are typically packaged in JAR packages.
  • <filter>: true or false, indicating whether to replace some property references in the resource file. Note that if you want to replace a reference to property, you do not have to define the <filters>definition*.properties file. The resource can also use the property defined by default in the POM (for example, ${project.version}), the -D option parameter passed to the command line.(for example, -Dname=value) or property explicitly defined by the <properties>element.
  • <directory>: The value of this element defines where resources can be found, defaulting to ${basedir}/src/main/resources.
  • <include>: A set of file patterns that use * as a wildcard character to specify which files and directories in the directory specified by the <directory>element value are to be included in the <targetPath>directory.
  • <excludes>: Same as <include>element structure, but specifies files to exclude. If a path matches both <include>and <excludes>patterns, the matching inclusion pattern is ignored and the processing is excluded.
  • <testResources>:<testResources> elements contain <testResource> elements. Their definitions are similar to those of resource elements but are used naturally during the testing phase. One difference is that the default (super POM-defined) test resource directory for the project is ${basedir}/src/test/resources. Test resources are not deployed.

Take another example of a Spring Boot project managing resource files in different operating environments:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <build>
    ...
    <!-- Declared for three running environments profile: Development, testing, UAT,Production. When passed id Activated a profile After that, the corresponding activeProfile Attributes work -->
    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <activeProfile>dev-res</activeProfile>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>

        <profile>
            <id>test</id>
            <properties>
                <activeProfile>test-res</activeProfile>
            </properties>
        </profile>
        <profile>
            <id>uat</id>
            <properties>
                <activeProfile>uat-res</activeProfile>
            </properties>
        </profile>
        <profile>
            <id>pro</id>
            <properties>
                <activeProfile>pro-res</activeProfile>
            </properties>
        </profile>
    </profiles>
    ...
	<resources>
		<resource>
        	<!-- The default resource directory is src/main/resources. It is recommended that resource files with the same name be stored separately in different environments -->
            <!-- If src/main/resources The following subpaths exist: env/dev-res/,env/test-res/,env/uat-res/,env/pro-res/,
			Some resource files corresponding to the running environment are stored under each subpath -->
        	<directory>src/main/resources</directory>
    		<!-- Exclude env All resource files under subdirectories -->
        	<excludes>
           		<exclude>env/**</exclude>
     		</excludes>
   		</resource>
        <!-- Use another resource Element to contain an active profile in activeProfile Resource Path Constructed by Attribute Values -->
        <!-- src/main/resources/env/${activeProfile} The resource files under the path will be copied directly to the class path where the output directory is built -->
      	<resource>
    		<directory>src/main/resources/env/${activeProfile}</directory>
        	<includes>
         		<include>**</include>
            </includes>
 		</resource>
	</resources>
    ...
  </build>
</project>

In the above example, by activating a profile, you can choose to src/main/resources/env/${activeProfile}Copying the resource files under the path to the class path where the output is built eliminates the need to replicate back and forth to replace the resource files in different running environments. If you are developing with Intellig IDEA, it is very convenient to activate the profile directly by checking the Profile check box provided by the Maven plug-in. You can also activate a profile by using command line parameters.

Plug-in unit

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <build>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.6</version>
        <extensions>false</extensions>
        <inherited>true</inherited>
        <configuration>
          <classifier>test</classifier>
        </configuration>
        <dependencies>...</dependencies>
        <executions>...</executions>
      </plugin>
    </plugins>
  </build>
</project>

In addition to the standard coordinates of groupId:artifactId:version, there are elements for configuring plug-ins or interacting with builds.

  • extensions: true or false, whether to load the extension for this plug-in. It defaults to false.

  • Inherited: true or false, whether the plug-in configuration applies to child POMs inherited from the POM. The default value is true.

  • Configuration: This is specific to individual plug-ins. Without going into the mechanics of how plug-ins work, just state any properties that the plug-in Mojo might expect (getter s and setter s in javamojobean s)You can specify it here. In the example above, we will set classifier as test in Mojo of maven-jar-plugin. It is worth noting that all configuration elements, regardless of where they are in the POM, are designed to pass values to another underlying system, such as plug-ins. In other words, POM syntax never explicitly declares that configuration is requiredThe value in the element, but the plug-in target has full authority to require that the value in the configurationelement be provided.

    If your POM inherits from a parent POM, it will inherit the plug-in configuration from the parent <build>/<plugins>elements and <pluginManagement>elements.

    Default Configuration Inheritance

    For illustration, look at the following snippet from a parent POM:

    <plugin>
      <groupId>my.group</groupId>
      <artifactId>my-plugin</artifactId>
      <configuration>
        <items>
          <item>parent-1</item>
          <item>parent-2</item>
        </items>
        <properties>
          <parentKey>parent</parentKey>
        </properties>
      </configuration>
    </plugin>
    

    The project in which the following POM fragment resides inherits the project in which the above POM fragment resides:

    <plugin>
      <groupId>my.group</groupId>
      <artifactId>my-plugin</artifactId>
      <configuration>
        <items>
          <item>child-1</item>
        </items>
        <properties>
          <childKey>child</childKey>
        </properties>
      </configuration>
    </plugin>
    

    The default behavior is to merge the contents of configuration elements based on the element name. If the child POM has elements that are not present in the parent POM, or if the child POM has the same elements as the parent POM, the element in the child POM will become a valid value. If the parent POM has all elements that are not present in the child POM, the element in the parent POM will become a valid value. This is purely XML.The operation does not involve the code or configuration of the plug-in itself. It only involves elements, not their values.

    Applying these rules to the example, the actual results in the sub-POM are as follows:

    <plugin>
      <groupId>my.group</groupId>
      <artifactId>my-plugin</artifactId>
      <configuration>
        <items>
          <item>child-1</item>
        </items>
        <properties>
          <childKey>child</childKey>
          <parentKey>parent</parentKey>
        </properties>
      </configuration>
    </plugin>
    

    Advanced Configuration Integration

    By adding attributes to the child elements of the <configuration>element, you can control how the child POM inherits the configuration from the parent POM. The attributes are combine.children and combine.self. Use these attributes in the child POM to control how Maven combines the parent's plug-in configuration with the child's explicit configuration.

    The following are examples of two attributes in a subconfiguration:

    <configuration>
      <items combine.children="append">
        <!-- combine.children="merge" is the default -->
        <item>child-1</item>
      </items>
      <properties combine.self="override">
        <!-- combine.self="merge" is the default -->
        <childKey>child</childKey>
      </properties>
    </configuration>
    

    Then, the effective configuration is as follows:

    <configuration>
      <items combine.children="append">
        <item>parent-1</item>
        <item>parent-2</item>
        <item>child-1</item>
      </items>
      <properties combine.self="override">
        <childKey>child</childKey>
      </properties>
    </configuration>
    

    Combine.children="append" will connect values in parent and child elements sequentially. On the other hand, combine.self="override" completely overrides the corresponding parent configuration. If you try to use combine.self="override" and combine.children="append" for an element at the same time, override will take the upper hand.

    Note that these attributes apply only to configuration elements that declare them, not to nested child elements that propagate to the next level. That is, if the content of the <item>element from the child POM is a complex structure and not text, its child elements will still follow the default merge policy unless they use the combined. * attribute combination. *Attributes inherit from the parent POM to the child POM. Be careful when adding these attributes to the parent POM, as this may affect its child POM or its grandchild POM.

  • Dependencies: The <dependencies>element can be seen in many places in the POM, and when it can appear in the <plugin>element, it has the same structure and function as it did under the infrastructure. The difference is <dependencies>under the <plugin>element.Elements are no longer dependent on the project but on the plug-in in which they are located. Their function is to change the list of dependencies of the plug-in, either by excluding deletion of unused runtime dependencies or by changing the version of the required dependency.

  • Executions: A plug-in may have multiple targets. Each target may have a separate configuration, or it may even bind the target of the plug-in to a different stage. <executions>Configure <execution> for a plug-in target. For example, suppose you want to bind the antrun:run target to the verify phase. We want the task echo to build the directory and inherited it bySet to false to avoid passing this configuration to its children (assuming it is the parent). You will get the following <execution>:

    <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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      ...
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.1</version>
            <executions>
              <execution>
                <id>echodir</id>
                <goals>
                  <goal>run</goal>
                </goals>
                <phase>verify</phase>
                <inherited>false</inherited>
                <configuration>
                  <tasks>
                    <echo>Build Dir: ${project.build.directory}</echo>
                  </tasks>
                </configuration>
              </execution>
            </executions>
     
          </plugin>
        </plugins>
      </build>
    </project>
    
    • Id: Self-explanatory, used to identify the execution block in all execution blocks. When the phase runs, it will be displayed as [plugin:goal execution: id]. In this case: [antrun:run execution: echodir].
    • goals: Like all POM elements with plural names, it is a list of <goal>elements.
    • phase: This is the stage at which the <goals>list is executed. This is a very powerful option to change Maven's default behavior by allowing any target to be bound to any stage of the build lifecycle.
    • Inherited: As with the <inherited>element above, setting this to false will prevent Maven from passing this execution to its children. This element is meaningful only to the parent POM.
    • configuration: Same as above, but configures to this specific target list, not to all targets under the plug-in.

Plug-in Management

<pluginManagement>is an element at the same level as <plugins>that manages plug-ins. <pluginManagement>elements contain plug-in elements in much the same way as <plugins>elements, except that the definition here only provides default configurations for plug-ins that are actually referenced in subprojects or in the <plugins>elements of the current project, if the subproject or the current projectIf some plug-in declarations in the <plugins Management>element are not used in the <plugins>element, the corresponding plug-in will not be used in the subproject or the current project. Subprojects can completely override the definition of inherited plug-in management.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <build>
    ...
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>2.6</version>
          <executions>
            <execution>
              <id>pre-process-classes</id>
              <phase>compile</phase>
              <goals>
                <goal>jar</goal>
              </goals>
              <configuration>
                <classifier>pre-process</classifier>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
    ...
  </build>
</project>

If a child POM inherits the above POM through the following fragments, or if the current POM contains the above <pluginManagement>element declaration and at the same time declares the configuration of the following fragments in the current POM, then the corresponding plug-in can be used exactly as declared by the <pluginManagement>element, without having to copy it completely, as it has already been declared from the <pluginManagement>elementThe <pluginManagement>element inherits some default plugin configurations.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <build>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
      </plugin>
    </plugins>
    ...
  </build>
</project>

Other elements in <build>

The Build type in XSD represents those elements that can only be used for project building. Despite the many additional elements, <project>/<build>actually contains only two sets of elements that are missing from <profile>/<build>: directories and extensions.

Catalog

The set of directory elements is in the parent <build>element, and the parent <build>element sets the POM as a whole to various directory structures. Because they do not exist in <profile>/<build>, they cannot be modified by <profile>.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <build>
    <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
    <outputDirectory>${basedir}/target/classes</outputDirectory>
    <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
    ...
  </build>
</project>

If the value of the <*Directory>element above is set to an absolute path (when its property is replaced with the actual value), then the absolute path is used. Otherwise, the relative path relative to the ${basedir} directory is used. Note that scriptSourceDirectory is not used in Maven and is obsolete.

extend

Extend (through <extensions>elements)Is a list of artifacts to be used in this build, which will be included in the running build's class path to support extensions to the build process and to activate plug-ins to change the build life cycle. In short, extensions are artifacts that are activated during the build. Extensions do not have to actually perform any action or include Mojo. Therefore, extensions are well suited to one of several implementations that specify a common plug-in interface.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <build>
    ...
    <extensions>
      <extension>
        <groupId>org.apache.maven.wagon</groupId>
        <artifactId>wagon-ftp</artifactId>
        <version>1.0-alpha-3</version>
      </extension>
    </extensions>
    ...
  </build>
</project>

reporting

The <report>element contains elements related to the site generation phase. Some Maven plug-ins can generate reports that are defined and configured under the <report>element, such as generating Javadoc reports. Much like the <build>element configuration plug-in, the <report>element has the same functionality. The obvious difference is that the <report>element is in the <reportSet>Configure the target in the element, rather than fine-grained control over the plug-in target in the <executions>element. A more subtle difference is that the <configuration>of the plug-in under the <reporting>element can be used as the <configuration> of the plug-in in <build>, although this is not the case: <build>The plug-in <configuration>does not affect the plug-in in <reporting>

The only element that people who know the <build>element may not be familiar with the <report>element is the <excludeDefaults>element of the Boolean type. This element instructs the site builder to exclude reports that are normally generated by default. When a site is generated through the site build cycle, a Project Info section appears in the left menu that contains a large number of reports, such as Project Team Reports or Dependencies list reports. These report targets are generated by the maven-project-info-reports-plugin plug-in. Like other plug-ins, it may be suppressed in more detail below to effectively close project information reporting.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <reporting>
    <outputDirectory>${basedir}/target/site</outputDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-project-info-reports-plugin</artifactId>
        <version>2.0.1</version>
        <reportSets>
          <reportSet></reportSet>
        </reportSets>
      </plugin>
    </plugins>
  </reporting>
  ...
</project>

Another difference is the <outputDirectory>element under <plugin>. Under <reporting>, the output directory defaults to ${basedir}/target/site.

It is important to remember that a plug-in may have multiple goals. Each target may have a separate configuration. <reportSets>Configure the execution of the goals of a report class plug-in, which sounds familiar? The same thing is said about the <execution>element that was built, but with one difference: the goals of a report class plug-in cannot be bound to another stage.

For example, suppose we want to configure links to http://java.sun.com/j2se/1.5.0/docs/api/ The javadoc:javadoc target of, but only the Javadoc target (not maven-javadoc-plugin:jar). We also want to pass this configuration to its children and set <inherited>to true. <reportSets>Similar to the following:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <reporting>
    <plugins>
      <plugin>
        ...
        <reportSets>
          <reportSet>
            <id>sunlink</id>
            <reports>
              <report>javadoc</report>
            </reports>
            <inherited>true</inherited>
            <configuration>
              <links>
                <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
              </links>
            </configuration>
          </reportSet>
        </reportSets>
      </plugin>
    </plugins>
  </reporting>
  ...
</project>

Between <executions>of <build>and <reportSets>of <reporting>it should now be clear why they exist. POM must have a way to configure plug-ins as well as a way to configure their goals. This is where these elements are used so that POM can control its build behavior with the finest granularity.

More Project Information

Several elements do not affect the build, but document the project for developers. Many of these elements are used to fill in project details when building a project site. However, like all POM declarations, plug-ins can use them for anything. Here are the simplest elements:

  • name: In addition to artifactId, projects often have informal names. Sun's engineers did not refer to their project as java-1.5, but just as Tiger. Here's where the value is set.
  • Description: A short, easy-to-read description of the project. Although this should not replace formal documentation, it is always helpful to have quick comments from any POM reader.
  • url: The home page of the project.
  • inceptionYear: The year in which the project was originally created.

licenses

<licenses>
  <license>
    <name>Apache License, Version 2.0</name>
    <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
    <distribution>repo</distribution>
    <comments>A business-friendly OSS license</comments>
  </license>
</licenses>

<licenses>is a legal document that defines how and when to use a project (or part of a project). A project should list licenses that apply directly to the project, not those that apply to project dependencies.

  • name, url, and comments: are self-explanatory and have been encountered in other contexts before. Recommended SPDX The identifier is used as the license name. The fourth license element is:
  • distribution: Describes how to legally publish a project. Two methods are repo (which can be downloaded from the Maven repository) or manual (which must be installed manually).

organization

Most projects are run by an organization (business, private groups, etc.). This is where the most basic information is set.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <organization>
    <name>Codehaus Mojo</name>
    <url>http://mojo.codehaus.org</url>
  </organization>
</project>

developers

All projects consist of files created by one person at a certain time. As with other systems around the project, people participating in the project have an interest in the project. Developers may be members of the core development of the project. Note that although an organization may have many developers (programmers)Being a member but listing them all as developers is not a good way to list only those who are directly responsible for the code. A good rule of thumb is that if they should not be contacted for a project, they do not need to be listed here.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <developers>
    <developer>
      <id>jdoe</id>
      <name>John Doe</name>
      <email>jdoe@example.com</email>
      <url>http://www.example.com/jdoe</url>
      <organization>ACME</organization>
      <organizationUrl>http://www.example.com</organizationUrl>
      <roles>
        <role>architect</role>
        <role>developer</role>
      </roles>
      <timezone>America/New_York</timezone>
      <properties>
        <picUrl>http://www.example.com/jdoe/pic</picUrl>
      </properties>
    </developer>
  </developers>
  ...
</project>
  • id, name, email: These correspond to the developer's id (which may be the only id in the entire organization), the developer's name, and e-mail address.
  • Organization, organization Url: As you might guess, this is the developer's organization name and URL.
  • Roles: A role should specify the standard operation that the person is responsible for. Just like a person can wear many hats, a person can play multiple roles.
  • timezone: A valid time zone ID, such as America/New_York or Europe/Berlin, or a numeric offset in hours (and minutes) based on the UTC time the developer resides in, such as -5 or + 1. Time zone IDs are preferred because they are not affected by DST and time zone offsets. Related official time zone databases and Wikipedia For a list in the IANA.
  • properties: This element is where any other attributes about this person are located. For example, links to personal images or instant messaging. Different plug-ins may use these attributes, or they may only be for other developers reading POM.

contributors

<contributors>Just like developers, plays a supporting role in the life cycle of a project. Perhaps the contributor sent a bug fix or added some important documentation. A healthy open source project may have more contributors than the developer.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <contributors>
    <contributor>
      <name>Noelle</name>
      <email>some.name@gmail.com</email>
      <url>http://noellemarie.com</url>
      <organization>Noelle Marie</organization>
      <organizationUrl>http://noellemarie.com</organizationUrl>
      <roles>
        <role>tester</role>
      </roles>
      <timezone>America/Vancouver</timezone>
      <properties>
        <gtalk>some.name@gmail.com</gtalk>
      </properties>
    </contributor>
  </contributors>
  ...
</project>

<contributors>contains the same set of elements as a developer without an id element.

Environment Settings

issueManagement

<issueManagement>defines the defect tracking system used (Bugzilla, TestTrack, ClearQuest, etc.). Nothing prevents a plug-in from using this information for something, but it is primarily used to generate project documents.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <issueManagement>
    <system>Bugzilla</system>
    <url>http://127.0.0.1/bugzilla/</url>
  </issueManagement>
  ...
</project>

Continuous Integrated Management

Over the past few years, continuous integrated building systems based on triggers or timers (e.g., hourly or daily) has become increasingly popular with manual builders. As building systems become more standardized, systems running triggers also trigger these builds. Although most configurations depend on the specific programs used (Continuum, Cruise Control, etc.)However, there are some configurations that may occur within the POM. Maven captures some duplicate settings in the <notifier>element. <notifier>is a way to notify people of certain build states. In the following example, this POM is setting up a notification program for the mail type and configuring the e-mail address to be used for the specified triggers sendOnError, sendOnFailure instead of sendOnSuccess Or sendOnWarning.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <ciManagement>
    <system>continuum</system>
    <url>http://127.0.0.1:8080/continuum</url>
    <notifiers>
      <notifier>
        <type>mail</type>
        <sendOnError>true</sendOnError>
        <sendOnFailure>true</sendOnFailure>
        <sendOnSuccess>false</sendOnSuccess>
        <sendOnWarning>false</sendOnWarning>
        <configuration><address>continuum@127.0.0.1</address></configuration>
      </notifier>
    </notifiers>
  </ciManagement>
  ...
</project>

mailing list

Mailing lists are a great tool for people to keep in touch with projects. Most mailing lists are for developers and users.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <mailingLists>
    <mailingList>
      <name>User List</name>
      <subscribe>user-subscribe@127.0.0.1</subscribe>
      <unsubscribe>user-unsubscribe@127.0.0.1</unsubscribe>
      <post>user@127.0.0.1</post>
      <archive>http://127.0.0.1/user/</archive>
      <otherArchives>
        <otherArchive>http://base.google.com/base/1/127.0.0.1</otherArchive>
      </otherArchives>
    </mailingList>
  </mailingLists>
  ...
</project>
  • Subscribe, unsubscribe: These elements specify the e-mail address used to perform operations to subscribe to the user list above. To subscribe to the user list above, the user will submit to user-subscribe@127.0.0.1 Send e-mail.
  • archive: This element specifies the URLs (if any) of the old mailing list e-mail archives. If mirrored archives exist, they can be specified under <otherArchives>.
  • post: The e-mail address used to send messages to mailing lists. Note that not all mailing lists can be sent (for example, build failure lists).

SCM

SCM (Software Configuration Management, also known as Source Code/Control Management, or simply version control) is a component of any health project. If your Maven project uses a SCM system, you can put this information into POM here.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <scm>
    <connection>scm:svn:http://127.0.0.1/svn/my-project</connection>
    <developerConnection>scm:svn:https://127.0.0.1/svn/my-project</developerConnection>
    <tag>HEAD</tag>
    <url>http://127.0.0.1/websvn/my-project</url>
  </scm>
  ...
</project>
  • Connection, developerConnection: These two connection elements indicate how to connect to the version control system via Maven. If the connection requires read access, Maven can find the source code. If it needs to be updated, developerConnection needs to provide write access. Maven hatched another project called Maven SCM, which is any connection that you want to implement itSCM created a public API. Most popular are CVS and ubversion, but others are supported List of SCM s There is also an increasing number of SCM connections. All SCM connections are made through a common URL structure.

    scm:[provider]:[provider_specific]
    

    Where provider is the type of SCM system. For example, a connection to a CVS repository might look like this:

    scm:cvs:pserver:127.0.0.1:/cvs/root:my-project
    
  • Tag: Specifies the tag where this item is located. HEAD (meaning SCM root) should be the default value.

  • url: A browsable repository can be exposed. For example, via ViewCVS.

The usual format for SCM URL s is scm:<scm_provider><delimiter><provider_specific_part>. You can use a colon: as a delimiter, or if you want to use a colon for one of these variables, such as a Windows path, you can use a pipe |. Here is a fully implemented SCM:

For example, for Git, we use a colon for all URLs below: as a delimiter. If you use a colon for one of these variables, such as a Windows path, use pipe | as the delimiter. The delimiter for a port must be a colon in all cases, as this part is specified in the git URL specification. See the git-fetch manual.

scm:git:git://server_name[:port]/path_to_repository
scm:git:http://server_name[:port]/path_to_repository
scm:git:https://server_name[:port]/path_to_repository
scm:git:ssh://server_name[:port]/path_to_repository
scm:git:file://[hostname]/path_to_repository

Example

scm:git:git://github.com/path_to_repository
scm:git:http://github.com/path_to_repository
scm:git:https://github.com/path_to_repository
scm:git:ssh://github.com/path_to_repository
scm:git:file://localhost/path_to_repository

In some cases, read and write operations must use different URLs. For example, this may happen if they are acquired through the http protocol but can only be written to the repository through ssh. In this case, both URLs can be written to the <developerConnection>element. The fetch URL must be prefixed with [fetch=], and the push URL must be prefixed with [push=], for example:

<developerConnection>scm:git:[fetch=]http://mywebserver.org/path_to_repository[push=]ssh://username@otherserver:8898/~/repopath.git</developerConnection>

Starting with Maven SCM version 1.3, we assume that the branch name in the remote warehouse is the same as the name of the current local branch. Therefore, whenever a maven-scm operation that must access the remote warehouse is invoked, you should be on that branch. In other words, if no branch is specified manually, then each git-fetch, git-pull, git-push Etc. will always work on a branch in the remote warehouse that has the same branch name as the current local branch:

git push pushUrl currentBranch:currentBranch

provider configuration is defined in ${user.home}/.scm/git-settings.xml. It is as follows:

<git-settings xmlns="http://maven.apache.org/SCM/GIT/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SCM/GIT/1.1.0 http://maven.apache.org/xsd/scm-git-1.1.0.xsd">
  <revParseDateFormat/>
  <traceGitCommand/>
  <gitCommand/>
  <commitNoVerify/>
</git-settings>
  • The git format allowed by the revParseDateFormat:changelog command defaults to yyyy-MM-dd HH:mm:ss.
  • traceGitCommand: Tracks the execution of git commands. Can be 1, 2, true or file location. Default is an empty string.
  • The current name of the gitCommand:git executable. Default is git.
  • commitNoVerify: Use the option--no-verify (which prevents cygwin from having trailing spaces). The default is false.

Prerequisites

POM may have certain prerequisites for correct execution. For example, there may be a patch in Maven 2.0.3 that you need to deploy using sftp. In Maven 3, use The requireMavenVersion rule for the Maven Enforcer plug-in Or other rules to examine other aspects.

In Maven 2, here's where you provide the prerequisites for building: if these prerequisites aren't met, Maven will fail even before you start building. The only element in POM 4.0 that exists as a prerequisite is the <maven>element, which has the smallest version number. It's checked with Maven 2 and no longer appears in Maven 3.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <prerequisites>
    <maven>2.0.6</maven>
  </prerequisites>
  ...
</project>

Repositories

Repositories are collections of artifacts that follow the Maven warehouse catalog layout. In order to be a Maven warehouse artifact, the path of the project's POM file must be $BASE_REPO/groupId/artifactId/version/artifactId-version.pom, where $BASE_REPO can be the file directory of the local warehouse or the basic URL in the remote warehouse, and the rest of the path structures are the same.

A warehouse exists as a place to collect and store artifacts. Whenever a project depends on an artifact, Maven first attempts to use a local copy of the specified artifact. If the artifact does not exist in the local warehouse, it will attempt to download it from a remote warehouse. The <repositories>element in the POM specifies the alternate warehouse to search for.

Warehouses are one of the most powerful features of the Maven community. By default, Maven searches for central warehouses in the following locations:https://repo.maven.apache.org/maven2/, you can configure additional repositories in the repositories element of pom.xml.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <repositories>
    <repository>
      <releases>
        <enabled>false</enabled>
        <updatePolicy>always</updatePolicy>
        <checksumPolicy>warn</checksumPolicy>
      </releases>
      <snapshots>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
        <checksumPolicy>fail</checksumPolicy>
      </snapshots>
      <name>Nexus Snapshots</name>
      <id>snapshots-repo</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
      <layout>default</layout>
    </repository>
  </repositories>
  <pluginRepositories>
    ...
  </pluginRepositories>
  ...
</project>
  • Releases, snapshots: These are policies for each artifact type: releases or snapshots. With these two collections, POM can independently change each type of policy in a single repository. For example, you may decide to enable snapshot downloads only, possibly for development purposes.
  • Enabled: Indicates whether the warehouse has enabled artifacts of the corresponding type (releases or snapshots), true or false.
  • updatePolicy: This element specifies how often updates are attempted. Maven compares the timestamp of the local POM (stored in the Maven metadata file in the repository) to the remote POM. It can be: always, daily, interval:X (where X is an integer in minutes), never.
  • checksumPolicy: When Maven deploys a file to the repository, it also deploys the corresponding checksum file. You can choose to use ignore, fail, or warn when you encounter checksum file loss or inconsistency.
  • Layout: In the description above of the repositories, it is mentioned that they all follow a common layout. This is basically correct. The layout introduced by Maven 2 is the default layout of the repositories used by Maven 2 and 3; however, Maven 1.x has a different layout. Use this element to specify whether the default element or the traditional element.

Plugin Repositories

Warehouses are the locations of two main types of artifacts. The first artifact is the artifact that acts as a dependency, and most of the artifacts in the central warehouse are of this type. The other type of artifact is the plug-in, and the Maven plug-in itself is a special type of artifact. Because of this, the plug-in warehouse and the dependency warehouse may be separate (and then, in reality, they are not so many)In any case, the <pluginRepositories>element is structurally similar to the <repositories>element.

distributionManagement

The role of <distribution management>is to manage the artifacts generated throughout the build process and to support the deployment of artifacts.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <distributionManagement>
    ...
    <downloadUrl>http://mojo.codehaus.org/my-project</downloadUrl>
    <status>deployed</status>
  </distributionManagement>
  ...
</project>
  • downloadUrl: This URL is the warehouse address where Maven uploads the POM artifact for deployment, from which other users can download the POM artifact.
  • Status: Like a bird in a bird's nest, status should never be touched by hand! The reason is that Maven will set the status of the project when it is transferred to the warehouse. Its valid types are as follows.
    • none: No special state. This is the default setting for POM.
    • converted: The warehouse administrator converts this POM from an earlier version to Maven 2.
    • Partner: This artifact has been synchronized with the partner warehouse.
    • Deployed: By far the most common state, this means that the work was deployed through Maven 2 or 3. This is the result of deploying manually using the command line deployment phase.
    • verified: The project has been validated and should be considered completed.
Repository

The <repositories>element specifies in the POM where and how Maven downloads remote artifacts for use by the current project, and <distribution management>specifies where (and how) the project reaches the remote warehouse at deployment time. If <snapshotRepository> is not defined, the <repository>element will be used for snapshot distribution.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <distributionManagement>
    <repository>
      <uniqueVersion>false</uniqueVersion>
      <id>corp1</id>
      <name>Corporate Repository</name>
      <url>scp://repo/maven2</url>
      <layout>default</layout>
    </repository>
    <snapshotRepository>
      <uniqueVersion>true</uniqueVersion>
      <id>propSnap</id>
      <name>Propellors Snapshots</name>
      <url>sftp://propellers.net/maven</url>
      <layout>legacy</layout>
    </snapshotRepository>
    ...
  </distributionManagement>
  ...
</project>
  • id, name: The id is used to uniquely identify the warehouse in many warehouses, and the name is in a readable form.
  • uniqueVersion: Use a true or false value to indicate whether the artifacts deployed to this warehouse should get a unique version number, or use the version number defined in the address.
  • url: This is the core of the <repository>element. It specifies the location and transport protocol used to transfer construction artifacts (as well as POM files and checks and data) to the repository.
  • Layout: These types and uses are the same as the layout elements defined in the repository elements. They are default and legacy.
Site Distribution

The <distribution management>element is responsible not only for publishing to the repository, but also for defining the site and documentation for how the project will be deployed.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <distributionManagement>
    ...
    <site>
      <id>mojo.website</id>
      <name>Mojo Website</name>
      <url>scp://beaver.codehaus.org/home/projects/mojo/public_html/</url>
    </site>
    ...
  </distributionManagement>
  ...
</project>
  • id, name, url: These elements are similar to the corresponding elements in the repository element in <distribution management> above.
Relocation
<project xmlns="http://maven.apache.org/POM/4.0.0"1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <distributionManagement>
    ...
    <relocation>
      <groupId>org.apache</groupId>
      <artifactId>my-project</artifactId>
      <version>1.0</version>
      <message>We have moved the Project under Apache</message>
    </relocation>
    ...
  </distributionManagement>
  ...
</project>

Projects are not static, they are living things (or dying things, depending on the situation)As projects evolve, a common phenomenon is that they may be forced to move to a more suitable location. For example, when your next very successful open source project runs under Apache umbrella, it is best to let users know that the project will be renamedOrg.apache:my-project:1.0. In addition to specifying a new address, providing a message explaining the cause is also a good form.

Profiles

A new feature of POM 4.0 is that the project can change settings based on the build environment. <profiles>element contains optional <activation> (profile trigger) and a set of changes to the POM if the profile is activated. For example, the project built for the test environment has many different property configurations from the final deployed project.(such as database connection information, access address of associated services, etc.). Alternatively, dependencies can be extracted from different warehouses based on the version of JDK used. <profiles>elements are as follows:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <profiles>
    <profile>
      <id>test</id>
      <activation>...</activation>
      <build>...</build>
      <modules>...</modules>
      <repositories>...</repositories>
      <pluginRepositories>...</pluginRepositories>
      <dependencies>...</dependencies>
      <reporting>...</reporting>
      <dependencyManagement>...</dependencyManagement>
      <distributionManagement>...</distributionManagement>
    </profile>
  </profiles>
</project>
activation

Activation is the key to a profile. The power of a profile comes from its ability to modify the basic POM only in certain situations. These situations are specified by the <activation>element.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <profiles>
    <profile>
      <id>test</id>
      <activation>
        <activeByDefault>false</activeByDefault>
        <jdk>1.5</jdk>
        <os>
          <name>Windows XP</name>
          <family>Windows</family>
          <arch>x86</arch>
          <version>5.1.2600</version>
        </os>
        <property>
          <name>sparrow-type</name>
          <value>African</value>
        </property>
        <file>
          <exists>${basedir}/file2.properties</exists>
          <missing>${basedir}/file1.properties</missing>
        </file>
      </activation>
      ...
    </profile>
  </profiles>
</project>

Prior to Maven 3.2.2, activation occurred when one or more specified criteria were met. When the first positive result was encountered, processing stopped and the profile was marked active. Because Maven 3.2.2 activation occurred when all specified criteria were met.

  • jdk:activation has a built-in Java-centric check in a jdk element. If the version of the jdk that Maven builds matches the prefix specified in the jdk element value, the profile will be activated. In the example above, 1.5.0_06 can match. Matching scopes are also supported. For more details on supporting scopes, see maven-enforcer-plugin Plug-in unit.
  • os: This element defines some of the os-specific properties shown above. For more details on os values, see maven-enforcer-plugins RequireOS Rules.
  • Property: If Maven detects a system or command line property corresponding to a name=value pair (a value that can be dereferenced in the POM by ${name}), the profile will be activated.
  • File: Finally, a given filename may activate the profile through an existence or missing of the file. Note: Interpolation of this element is limited to ${basedir}, system attributes, and request attributes.

The <activation> element is not the only way to activate profiles. The activeProfile element in the settings.xml file may contain the id of the profile. It can also be explicitly activated by a comma-separated list following the -P flag (for example, -P codecoverage) on the command line.

To see which profile will be activated in a specific build, use maven-help-plugin.

mvn help:active-profiles

Keywords: Java Maven xml JavaSE IDE

Added by john8675309 on Sat, 11 Sep 2021 01:49:19 +0300