Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify transitive dependency's version in maven?

Tags:

maven

I have a dependency A which depend on B, while in A's pom file, B'version can be specified. So I want to know how can I specify B's version when building ? Thanks.

like image 738
zjffdu Avatar asked Sep 27 '16 04:09

zjffdu


2 Answers

As stated in other answers "transient dependency" involve 3 artifact

  • A depends on B
  • B depends on C

so C is a transitive dependency of A

What you want is control version number of a dependency for each running build. To do so you should bind the version number of that particular dependency to a maven property

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

    <artifactId>A</artifactId>
    <groupId>com.xyz</groupId>
    <version>1.0</version>



 <properties>
    <B_project_version>1.5</B_project_version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.xyz</groupId>
        <artifactId>B</artifactId>
        <version>${B_project_version}</version>
    </dependency>
</dependencies>

Now you can pass a parameter to your build to specify the value of "B_project_version" for example

man package -DB_project_version=3.8

If you do not specify any value for the proper the default value ( 1.5 in the above example) will be used

It is handy to define profiles for most likely scenarios with the definition of apposite profiles

 <profiles>
    <profile>
        <id>use_version_2</id>
        <properties>
            <B_project_version>2.0</B_project_version>
        </properties>
    </profile>
    <profile>
        <id>use_version_1</id>
        <properties>
            <B_project_version>1.0</B_project_version>
        </properties>
    </profile>
</profiles>

If your intent is to control a true transitive dependacy you have to exclude it form B dependency in your pom and make it a direct dependency. The above example becomes

<properties>
    <C_project_version>1.5</C_project_version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.xyz</groupId>
        <artifactId>B</artifactId>
        <version>1.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.xyz</groupId>
                <artifactId>C</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.xyz</groupId>
        <artifactId>C</artifactId>
        <version>${C_project_version}</version>
    </dependency>
</dependencies>


<profiles>
    <profile>
        <id>use_version_2</id>
        <properties>
            <C_project_version>2.0</C_project_version>
        </properties>
    </profile>
    <profile>
        <id>use_version_1</id>
        <properties>
            <C_project_version>1.0</C_project_version>
        </properties>
    </profile>
</profiles>

like image 157
Sammyrulez Avatar answered Nov 15 '22 09:11

Sammyrulez


To describe transitive dependencies we need three artifacts because its a dependency of a dependency.

Let's look at these three pom.xml files:

a/pom.xml:

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

    <groupId>x.y</groupId>
    <artifactId>a</artifactId>
    <version>2.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>x.y</groupId>
            <artifactId>b</artifactId>
            <version>2.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>x.y</groupId>
                <artifactId>c</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

b/pom.xml:

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

    <groupId>x.y</groupId>
    <artifactId>b</artifactId>
    <version>2.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>x.y</groupId>
            <artifactId>c</artifactId>
            <version>2.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

c/pom.xml:

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

    <groupId>x.y</groupId>
    <artifactId>c</artifactId>
    <version>2.0-SNAPSHOT</version>

</project>

In this example artifact a depends on b and artifact b depends on c.

Without the <dependencyManagement> block in a/pom.xml the artifacts b and c will be used in version 2.0-SNAPSHOT but with this "override" the artifact uses b in version 2.0-SNAPSHOT but the transitive dependency c in version 1.0-SNAPSHOT.

like image 45
Josef Reichardt Avatar answered Nov 15 '22 08:11

Josef Reichardt