The inheritance, aggregation, and dependency of Maven

Source: Internet
Author: User
One, Inherit 1, the inherited project is a parent-child directory relationship with the inherited item

PROJECTB in the ProjectA directory, the PROJECTB should be set 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 http://maven.apache.org/maven-v4_0_0.xsd" >
  < parent>
    <groupId>com.tiantian.mavenTest</groupId>
    <artifactid>projecta</ artifactid>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion> 4.0.0</modelversion>
  <groupId>com.tiantian.mavenTest</groupId>
  <artifactId> projectb</artifactid>
  <packaging>jar</packaging>
  <version>1.0-snapshot</ Version>
</project>

2, the inherited item is not a parent-child directory relationship

is not a parent-child directory, the parent element in the Pom.xml file definition of the subproject is followed by a definition of a RELATIVEPATH element that describes the location of the Pom.xml file for the child project relative to the Pom.xml file of the subproject.

For example, when a PROJECTA,PROJECTB peer is PROJECTB to inherit the ProjectA project, the following are:

<project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemalocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" >
  < parent>
    <groupId>com.tiantian.mavenTest</groupId>
    <artifactid>projecta</ artifactid>
    <version>1.0-SNAPSHOT</version>
       <relativepath> /projecta/pom.xml</relativepath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.tiantian.mavenTest</groupId>
  <artifactId>projectB</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
</ Project>

Two, polymerization

The project that is aggregated is the parent project or the Super project.

The benefits of aggregation, the MVN compile on the Super project, will be those child module projects are compiled, eliminating the trouble of execution. Specific practices:

Ø Modifying the value of the packaging element in the pom.xml of the aggregated project is POM
Ø specifies its child module project under the modules element in the pom.xml of the aggregated project
1, the aggregated project and the Child module project are the parent-child relationship in the directory structure

The directory structure looks like this:
------ProjectA
------PROJECTB
-----Pom.xml
------Pom.xml
This time ProjectA's pom.xml should be defined as this:

<project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemalocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
  < modelversion>4.0.0</modelversion>
  <groupId>com.tiantian.mavenTest</groupId>
  < artifactid>projecta</artifactid>
  <version>1.0-SNAPSHOT</version>
  <packaging >pom</packaging>
  <modules>
       <module>projectB</module>
  </modules>
</project>
The packaging type should be pom, and for this aggregation, we use the Artifactid of the Child module project as the value of the module, representing the child module project relative to the address of the aggregated project. In the above example, the child module PROJECTB is located in the subdirectory of the aggregated project, which is in the same directory as the pom.xml of the project being aggregated. The module value used here is the corresponding directory name PROJECTB of the PROJECTB, not the artifactid corresponding to the child module. At this point, when we mvn the package command for PROJECTA, maven actually packs PROJECTB.

2, the aggregated project and the Child module project are not parent-child relationships in the directory structure

The practice is to specify a child module in a module element in a relative way. For example, when you are at a peer, the aggregated item should be set 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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
  < modelversion>4.0.0</modelversion>
 
  <groupId>com.tiantian.mavenTest</groupId>
  < artifactid>projecta</artifactid>
  <version>1.0-SNAPSHOT</version>
  <packaging >pom</packaging>
  <modules>
       <module> /projectb</module>
  </modules>
</project>
Note that the value of module is ".. /PROJECTB ", we Know" ... " Is the top-level directory that represents the current directory, so it represents the child module PROJECTB is the subdirectory in the upper directory of the directory (that is, projecta) where the projecta of the Pom.xml file is aggregated, that is, the same directory level as the projecta. Note that the PROJECTB here corresponds to the directory name of the PROJECTB project, not its artifactid.
Third, Reliance How to use

In the dependency element we define the dependent project primarily by relying on the GroupID, Artifactid, and version of the project. In addition, you can specify the following elements:

Ø type: Corresponds to the packaging type of the dependent project, and the default is Jar
Ø scope: Represents a scope for dependent projects. The primary values for scope are as follows (there is an import that is supported later in the Maven2.0.9 version, and the import scope will be introduced in the later "Dependency Introduction"):
Compile: This is its default value, This type can easily be misunderstood, thinking that it is only needed at compile time, in fact this type means that all situations are useful, including compilation and runtime. And this type of dependency can be passed. Provided: This is similar to compile, but it means you expect the dependency project to be provided by the JDK or the container at runtime. This type indicates that the dependency is valid only for testing and compilation, and will be provided by the JDK or container at run time. This type of dependency is not transitive. Runtime: This type means that the dependency is not necessary at compile time, only when it is run. Test: This means that this dependency is required only when testing, and is normally not needed. Import: Introduction to import, you can see the introduction of dependencies in the following article.
System: This type is similar to provided, the only difference being that this type of dependency we have to provide the jar package ourselves, which needs to be used in conjunction with another element Systempath. Systempath will point to the path of the jar package on our system and must be the given absolute path. is as follows:

<project> ...
  <dependencies>
    <dependency>
      <groupId>sun.jdk</groupId>
      <artifactId> tools</artifactid>
      <version>1.5.0</version>
      <scope>system</scope>
      <systempath>${java.home}/.. /lib/tools.jar</systempath>
    </dependency>
  </dependencies>
  ...
</project>
Øsystempath: It has been said that this element is used to specify the location of the dependent jar package on the system when the value of scope is systems, and is the absolute path. The element must be used when the scope of the dependent jar package is system, or MAVEN will complain.
Øoptional: Mark this dependency as optional when the project itself is a dependency on another project. Assuming that ProjectA now has a dependency projectb, we set PROJECTB this dependency to optional, which means that PROJECTB is not necessarily used when the projecta is running. This time if we have another project PROJECTC and it relies on projecta, then because PROJECTB is optional for projecta, MAVEN does not install PROJECTC when it is established PROJECTB, This time, if PROJECTC really needs to use the PROJECTB, then it can define its dependence on PROJECTB. When a dependency is optional, we set the value of the optional element to true, otherwise the optional element is not set.
Øexclusions: Considering such a situation, our projecta depends on the PROJECTB, then PROJECTB depends on PROJECTC, but in projecta we don't need PROJECTB dependent PROJECTC, Then we can use the exclusion of the exclusions element to exclude PROJECTC when relying on PROJECTB. This is the time we can define PROJECTA's reliance on PROJECTB:

  <dependencies>
       <dependency>
              <groupId>com.tiantian.mavenTest</groupId>
              < artifactid>projectb</artifactid>
              <version>1.0-SNAPSHOT</version>
              <exclusions >
                     <exclusion>
                            <groupId>com.tiantian.mavenTest</groupId>
                            <artifactId> projectc</artifactid>
                     </exclusion>
              </exclusions>
       </dependency>
  < /dependencies>
the transitivity of dependence

Assuming a->b->c->d1.0,a->e->d2.0, then a will choose to rely on a component with a short d relative path, that is, D2.0. So how does maven choose when the depth is the same? That is, a->b->d1.0 and a->c->d2.0, how will maven choose the version of D that a relies on? In this case Maven chooses according to the stated dependency order, which is declared as a dependency package. To the previous case, if the dependency on B is first stated, then a depends on D1.0, and if the dependency on C is first stated, a depends on the D2.0.

Optional Dependencies

An optional dependency represents a dispensable, not necessarily required, and it just makes a mark. For the sake of understanding, let's look at a situation where project B depends on Project C, this time, we mark B's dependence on C using optional as optional, which means that only parts of B are used in C, not necessarily, when you rely on B, but do not need to use the C function of B, Can be independent of C. So when a->b->c, you will not be dependent on C when you build project A, because C is optional for B, we don't necessarily use C. But when you build project B, Maven adds dependencies to C. This means that this optional-marked dependency has little effect on the project itself, and it affects other projects that are dependent on the project, such as Project a here. One advantage of this optional dependency is that it will be excluded as a exclusion item by default. dependencymanagement Introduction dependencymanagement has two main functions, one is to centrally manage the dependencies of the project, and the other is to control the version of the dependencies that are used.
1, centrally manage dependencies

ProjectA relies on groupc:artifactc:1.0,groupd:artifactd:1.0, PROJECTB in groupc:artifactc:1.0,groupe:artifacte:1.0. They all depend on ARTIFACTC so that we can create a new project and use its dependencymanagement to manage these dependencies uniformly. We create project p to manage these dependencies:

<project> ... <dependencyManagement> <dependencies> ;d ependency> <groupId>groupC</groupId> <artifact Id>artifactc</artifactid> <version>1.0</version> 
                            ;/dependency> <dependency> <groupId>groupD</groupId> <artifactId>artifactD</artifactId> <version>1.0
                            </version> </dependency> <dependency>
                            <groupId>groupE</groupId> <artifactId>artifactE</artifactId>
                     <version>1.0</version> <type>bar</type> </depenDency> </dependencies> </dependencyManagement> ... </project> 
Then we can define our projecta and PROJECTB.
ProjectA:

<project>
       <modelVersion>4.0</modelVersion>
       <groupId>groupA</groupId>
       <artifactId>artifactA</artifactId>
       <version>1.0</version>
       < dependencies>
              <dependency>
                     <groupId>groupC</groupId>
                     <artifactId> artifactc</artifactid>
              </dependency>
              <dependency>
                     <groupid>groupd</ groupid>
                     <artifactId>artifactD</artifactId>
              </dependency>
       </ Dependencies> ...
</project>
As we can see from the above definition, we have simplified the definition of projecta and PROJECTB dependencies, and we can only declare the dependencies that need to be used in projecta and PROJECTB, without having to specify the corresponding version and scope of the information, When this information is specified, the definition in the subproject overrides the definition in the dependencymanagement of the parent project, otherwise the definition in dependencymanagement is used. This also makes it easy for us to manage the version of the dependency.
2, control the version used by the dependenciesLook at one of the following
ProjectA

<project> <modelVersion>4.0</modelVersion> <groupId>groupA</groupId> <artif Actid>artifacta</artifactid> <version>1.0</version> <packaging>pom</packaging&
       Gt
                            <dependencyManagement> <dependencies> <dependency>
                            <groupId>groupA</groupId> <artifactId>A</artifactId> <version>1.5</version> </dependency> < Dependency> <groupId>groupA</groupId> <artifacti D>b</artifactid> <version>1.0</version> </depende
                     Ncy> <dependency> <groupId>groupA</groupId>       <artifactId>C</artifactId> <version>1.0</version> </dependency> <dependency> <groupid>groupa</ Groupid> <artifactId>D</artifactId> <version> 1.6</version> </dependency> </dependencies> </dependencyman Agement> ... </project>
ProjectB

<project> <modelVersion>4.0</modelVersion> <groupId>groupB</groupId> &L T;artifactid>artifactb</artifactid> <version>1.0</version> <packaging>pom</pac
                            kaging> <dependencyManagement> <dependencies> <dependency> <groupId>groupA</groupId> <artifactid>a</arti
              Factid> <version>1.0</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency > <groupId>groupA</groupId> <artifactid>b</artifactid&gt
                     ;
                     <version>1.8</version> </dependency> <dependency><groupId>groupA</groupId> <artifactId>C</artifactId>  ;scope>runtime</scope> </dependency> </dependencies> ... </project>
Thus, when we perform MAVEN operations on PROJECTB, dependencies A, B, C, and D will be selected as follows:
When a is a dependency of B or C, PROJECTB will use the 1.0 version of A, because a is stated in PROJECTB's dependencymanagement, in addition to stating that the dependencies in Dependencymanagement will have a higher priority than the dependencies of the project's dependencies, as well as the statement of the current project will have a higher priority than the declaration of its parent project.
Dependency B will use version 1.8 because dependency B is declared directly in PROJECTB, and version 1.8 is specified, so the version of the current project declaration overwrites the version specified in the parent project's dependencymanagement.
Dependency C will use version 1.0, but its scope will be runtime. Because dependency C is also declared directly in PROJECTB, and it does not specify the version that it uses, the version specified in the dependencymanagement of its parent project is used. In addition, it specifies that the scope of its action is runtime, so it overrides the default compile scope of the dependencies specified in the dependencymanagement of its parent project.
Dependency D will use version 1.6. When D is a dependency of B or C, PROJECTB will use version 1.6 of D because Project D is declared in Dependencymanagement, and the dependencies declared in Dependencymanagement will have a higher priority than indirect dependencies.
3, introducing dependencies

We know that by inheriting a project we can well affirm the dependencies of the dependencymanagement definition of the parent project that needs to be used in the subproject. However, because each project can only declare a single parent project, this will at some point limit the establishment of our project. For this, MAVEN provides us with a way to import by setting the scope of a dependency. Note that this method is only available in Maven2.0.9 versions.

<project> ... <groupId>groupA</groupId> <artifactid>artifacta</artifactid&
       Gt
              <version>1.0</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupid>test</ Groupid> <artifactId>A</artifactId> <version>
                            1.0</version> </dependency> <dependency>
                            <groupId>test</groupId> <artifactId>B</artifactId> <version>1.1</version> </dependency> <depen Dency> <groupId>test</groupId> <artifactid>c& Lt;/artifactiD> <version>1.2</version> </dependency> <dependency> <groupId>test</groupId> &L T;artifactid>d</artifactid> <version>1.3</version> & Lt;/dependency> </dependencies> </dependencyManagement> ... </project>
The above project is used to unify the management of the project dependencies. So according to the previous inheritance mechanism, this time our project ARTIFACTB is defined as follows:
<project> ... <parent> <groupId>groupA</groupId> <artifactId>artifactA</artifactId> <version>1.0</version> </par ent> <groupId>groupA</groupId> <artifactId>artifactB</artifactId> <vers ion>1.0</version> <packaging>pom</packaging> <dependencies> <DEP Endency> <groupId>test</groupId> <artifactid>a</artifact id> </dependency> <dependency> <groupid>test</gro Upid> <artifactId>D</artifactId> <SCOPE>RUNTIME</SCOPE&G
              T </dependency> </dependencies> ... </project> 
So if you follow this form of import, ARTIFACTB can be defined as follows:
<project> ... <groupId>groupA</groupId> <artifactid>artifactb</artifactid&
       Gt
              <version>1.0</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <span style= "COLOR: #f f0000; "
                            ><groupId>groupA</groupId> <artifactId>artifactA</artifactId>
                            <version>1.0</version> <type>pom</type>
              <scope>import</scope></span> </dependency>
                     </dependencies> </dependencyManagement> <dependencies> <dependency>
            <groupId>test</groupId> <artifactId>A</artifactId>  </dependency> <dependency> <groupId>test</groupId> <artifactId>D</artifactId> <scope>runtime</scope> &L T;/dependency> </dependencies> ... </project>





Reference:

Introduction to Maven (V)--pom.xml

Introduction to Maven (vi)--dependency

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.