MAVEN's transitive dependencies and its jar pack conflict resolution __maven

Source: Internet
Author: User
Tags pack log4j

First, Maven Introduction

MAVEN is a Cross-platform project management tool. As a successful open source project for the Apache organization, it serves primarily in the Java Platform based project creation, dependency management, and project information management.


II. MAVEN's dependency management

1. Dependent configuration

Basic configuration:

<project> ...
  <dependencies>  
    <dependency>  
      <groupId>...</groupId>  
      <artifactid> .... </artifactId>  
      <version>...</version>
      <type>...</type>
      <scope> ...</scope>
      <optional>...</optional>
      <exclusions>  
        <exclusion>  
          <groupId>...</groupId>  
          <artifactId>...</artifactId>  
        </exclusion>
         ...
      </exclusions>  
    </dependency> 
     ...
  </dependencies> ... 
</project>

The dependencies under project under the root element can contain one or more dependency elements to declare one or more project dependencies. The elements that each dependency can contain are:
Groupid,artifactid and version:The basic coordinates of the dependencies, the basic coordinates are the most important for any dependency, and Maven can find the required dependencies based on the coordinates. Type:The type of dependency, corresponding to the packaging defined by the project coordinates. In most cases, the element does not have to be declared, and its default value is the jar. Scope:Depending on the scope, the following will be detailed. Optional:Whether the tag dependency is optional. Exclusions:Used to exclude transitive dependencies

Most dependency declarations contain only basic coordinates


2, the scope of dependence

MAVEN uses a set of CLASSPATH when compiling the main code, uses a different set of classpath when compiling and executing tests, and uses a set of classpath when it actually runs the project.
The dependency range is used to control dependencies on relationships with these three classpath (compile classpath, test classpath, run Classpath), and Maven has the following dependencies: compile: compilation dependency scope. If not specified, the dependency range is used by default. Using Maven dependencies of this dependency range is valid for compiling, testing, and running three kinds of classpath. A typical example is Spring-core, which needs to be used when compiling, testing, and running. provided: A dependency range has been provided. Using Maven dependencies of this dependency range is valid for compilation and test Classpath, but is not valid at run time. A typical example is SERVLET-API, which requires this dependency when compiling and testing a project, but when running a project, because the container is already available, there is no need for MAVEN to introduce it over and over again. Test : tests the dependency range. Maven dependencies with this dependency range are valid only for test classpath, and cannot be used when compiling the main code or running the project's use. A typical example is JUnit, which is only needed when compiling test code and running tests. Runtime: Run- time dependency range. Maven dependencies with this dependency range are valid for test and run classpath, but are not valid when compiling the main code. A typical example is the JDBC driver implementation, where the project's main code is compiled with the JDBC interface provided by the JDK, and it is only necessary to implement the specific JDBC driver for the above interface when executing the test or running the project. System : range of systems dependencies. This dependency range is consistent with the scope of dependencies represented by provided, valid for compilation and test classpath, but not valid at run time. You must explicitly specify the path of the dependent file through the Systempath element when using system-wide dependencies only. Because such dependencies are not resolved through the Maven warehouse and are often bound to native systems and may result in a build that is not portable, they should be used with caution and systempath elements can reference environment variables.


3. Transitive dependence

Transitive dependency is a new feature added to the maven2 that you do not need to think about the library files that you rely on to rely on to automatically introduce dependent modules. For example, we rely on spring's library files, but spring itself is dependent, and if there is no transitive dependency, then we need to understand the spring project dependencies and add ourselves to our project. With a pass-through dependency mechanism, you don't have to think about what it relies on when you use the spring framework, and don't worry about introducing unwanted dependencies. maven resolves each of the directly dependent POM, introducing the necessary indirect dependencies into the current project in the form of a transitive dependency.

For example: A project uses Spring-core, and it relies on commons-logging from its widget pom http://repo1.maven.org/maven2/org/springframework/spring-core/ 4.3.2.release/spring-core-4.3.2.release.pom can be seen in the

<?xml version= "1.0" encoding= "UTF-8"?>-<project xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns= "http://maven.apache.org/POM/4.0.0" 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> Org.springframework</groupid> <artifactId>spring-core</artifactId> <version>4.3.2.

release</version> <name>spring core</name> <description>spring Core</description> <url>https://github.com/spring-projects/spring-framework</url>-<organization> <name> Spring io</name> <url>http://projects.spring.io/spring-framework</url> </organization>- <licenses>-<license> <name>the Apache Software license, Version 2.0</name> <url>http:// Www.apache.org/licenses/license-2.0.txt</url> <distribution>repo</distribution> </license> </licenses>-<developers>-<developer> <id>jhoeller</id> <name>juer Gen Hoeller</name> <email>jhoeller@pivotal.io</email> </developer> </developers>- <scm> <connection>scm:git:git://github.com/spring-projects/spring-framework</connection> <

Developerconnection>scm:git:git://github.com/spring-projects/spring-framework</developerconnection>

<url>https://github.com/spring-projects/spring-framework</url> </scm>-<issuemanagement> <system>Jira</system> <url>https://jira.springsource.org/browse/SPR</url> </ issuemanagement>-<dependencies>-<dependency> <groupId>commons-codec</groupId> < Artifactid>commons-codec</artifactid> <version>1.10</version> <scope>compile</ scope> <optional>true</optional> </dependency>-&LT;DEPENDENCY&GT <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version >1.2</version> <scope>compile</scope> </dependency>-<dependency> <groupId> log4j</groupid> <artifactId>log4j</artifactId> <version>1.2.17</version> <scope >compile</scope> <optional>true</optional> </dependency>-<dependency> < Groupid>net.sf.jopt-simple</groupid> <artifactId>jopt-simple</artifactId> <version> 5.0.2</version> <scope>compile</scope> <optional>true</optional> </dependency >-<dependency> <groupId>org.aspectj</groupId> <artifactid>aspectjweaver</ artifactid> <version>1.8.9</version> <scope>compile</scope> <optional>true</ optional> </dependency> </dependencies> </project>


You can see that you also rely on other builds. MAVEN relies on the secondary pom file for its dependencies, which enables it to be transitive.



Assuming that a depends on the b,b dependent on C, we say that A is the first direct dependence on B, B is the second direct dependency for C, and a is a transitive dependency on C. The range of the first direct dependence and the range of the second direct dependence determine the range of transitive dependencies.
The leftmost line represents the first direct dependency range, the top line represents the second direct dependency range, and the middle cross cell represents the transitive dependency range.


Compile Test provided Runtime
Compile Compile --- --- Runtime
Test Test --- --- Test
provided Provided --- Provided Provided
Runtime Runtime --- --- Runtime

Looking closely at the table above, we find this pattern:

When the scope of the second direct dependence is compile, the scope of transitive dependence is consistent with the range of the first direct dependence;
When the scope of the second direct dependence is test, the dependence is not transmitted;
When the scope of the second direct dependence is provided, only the range of the first direct dependence is transmitted also for provided dependence, the range of the tangential transitive dependence is likewise provided;
When the scope of the second direct dependence is runtime, the range of transitive dependencies is consistent with the range of the first direct dependence, but compile exceptions, at which point the range of transitive dependencies is runtime.


4. Maven's handling of transitive dependencies

Some dependencies, MAVEN will automatically process it according to the following principles

1. Short circuit priority: who is nearest to the use of dependent jar pack

C arrives at a for c->b->a

C arrives B for C->b

For example:

The version of Commons-io in A is 2.4

The version of Commons-io in B is 2.0

C relies on the b,b dependent on a

The JUnit package for C is version 2.0.

Because the reliance on short circuit is preferred

2. If both roads are the same length.

C arrives at a for c->a

C arrives B for C->b

Look at the two projects that are dependent on the Pom file who is in front of which version

For example:

The Common-io used here is version 2.4

        <dependency>
            <groupId>org.lonecloud.A</groupId>
            <artifactid>a</artifactid >
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!--c depends on B but will pass a dependency on-- >
        <dependency>
            <groupId>org.lonecloud.B</groupId>
            <artifactid>b</ artifactid>
            <version>0.0.1-SNAPSHOT</version>
            <!--The role of this label is to pass B's transitive dependency A to C-->
            <!--<exclusions> <exclusion> <groupId>org.lonecloud.A</groupId> <artifactid >A</artifactId> 
                </exclusion> </exclusions>-->
        </dependency>

C files Add a and B dependencies when who first load then use whose jar package

The following is a version of 2.0, which is the jar package in B

        <dependency>
            <groupId>org.lonecloud.B</groupId>
            <artifactid>b</artifactid >
            <version>0.0.1-SNAPSHOT</version>
            <!--The role of this label is to pass B's transitive dependency A to the C-->
            <!-- <exclusions> <exclusion> <groupId>org.lonecloud.A</groupId> <artifactid>a</ artifactid> 
                </exclusion> </exclusions>-->
        </dependency>
        <dependency>
            <groupId>org.lonecloud.A</groupId>
            <artifactId>A</artifactId>
            < Version>0.0.1-snapshot</version>
        </dependency>


III. MAVEN relies on Jar pack conflict resolution

1, to determine whether the jar is correct to be cited

1), add VM parameters when the project starts:-verbose:class

When the project is started, all loaded jars will be printed out similar to the following information:

Classpath loaded Jar

Class for specific load

We can look up the above information to find the corresponding jar is correctly dependent, the specific class loading situation, you can see the version number, determine whether due to dependency conflict caused by incorrect jar reference;

2), through Maven's own tools: MVN Dependency:tree

Concrete can be added after the-dverbose parameters, detailed parameters can go to their own search, not in detail here.

For example, the following Pom is analyzed

Run: mvn dependency:tree-dverbose

Output results:

Through the information inside you can see two jars are commons-logging dependencies, but the version is different. The detailed information inside shows references to commons-logging:commons-logging:jar:1.1 removed commons-logging:commons-logging:jar:1.0.3 (omitted for Duplicate).

3, in myeclipse or idea or eclipse in the Pom editor to open a pom file, in the Dependency Hierarchy tab, you can view the current Pom file shows the declaration of the jar package, And the implicit, dependent jar packages that are implicitly introduced in the jar of these display declarations.



This allows you to see which implicitly dependent jars will cause the jar bundle to conflict.

By using the above method we can see the reference Jar version number in the project, and then how to eliminate the jar that we don't want to build;

2. Conflict resolution

1 Add exclusion to the package referenced in Pom.xml, excluding dependencies

<dependency>
			<groupId>com.alibaba</groupId>
			<artifactid>dubbo</artifactid >
			<version>2.5.3</version>
			<exclusions>
				<exclusion>
					<artifactid >spring</artifactId>
					<groupId>org.springframework</groupId>
				</exclusion>
			</exclusions>
		</dependency>

Remove all dependencies

<dependency>
<groupId>com.alibaba</groupId>
<artifactid>dubbo</artifactid >
<version>2.5.3</version>
<exclusions>
<exclusion>
< artifactid>*</artifactid>
<groupId>*</groupId>
</exclusion>
</ Exclusions>
</dependency>

2 Right-click in the IDE to process, after processing, in Pom.xml will also add exclusion elements



 

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.