Maven - Detect Multiple Versions of the Same Dependency

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-20 09:37:17

问题


I just experienced a case of two direct dependencies of my maven project having two different versions of a particular transitive dependency.

In my particular case I had direct dependencies on the following:

    <dependency>
        <groupId>org.jclouds.driver</groupId>
        <artifactId>jclouds-sshj</artifactId>
        <version>${jclouds.version}</version>
    </dependency>

and

    <dependency>
        <groupId>org.mule.modules</groupId>
        <artifactId>mule-module-jersey</artifactId>
        <version>${mule.version}</version>
    </dependency>

Both of these dependencies had a (deep) transitive dependency on com.sun.jersey:jersey-core, but with different versions for each. Maven didn't fail on this or even warn (or if it did, I never saw it!) that such a thing was happening... and as such I never noticed it until debugging a problem that happened when the version of jersey-core brought in by the jclouds dependency caused some things to break.

Is there a maven plugin or some other tool that exists that will detect this sort of deep transitive dependency overriding and at least warn the user (or fail the maven execution) if it detects such a collision... even if the default maven behavior is to just pick the first version that appears when resolving dependencies?


回答1:


Use the Dependency Enforcer plugin. It will stop the build when dependencies don't converge properly.

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.0.1</version>
    <executions>
      <execution>
        <id>enforce</id>
        <configuration>
          <rules>
            <DependencyConvergence />
          </rules>
        </configuration>
        <goals>
          <goal>enforce</goal>
        </goals>
      </execution>
    </executions>
  </plugin>



回答2:


@Clement P has provided you with a perfectly good answer. Note however that it might be insufficient for multi-module projects.

The depedndencyconvergence goal of the enforcer plugin knows how to detect transitive dependency collisions, but a collision may hide itself in a different manner.

Suppose you have a multi-module project. Root is A and it has 2 sub modules, B1 and B2.

B1 declares a dependency on artifact a:b:c: 1.1, while B2 declares a dependency on artifact a:b:c: 2.0

In this case, if both modules are built and deployed with their dependencies- you will have a collision, but it is a kind the enforcer plugin does not know how to detect. Since project A doesn't (can't) depend on its sub modules.

In order to overcome this problem in our organization, we used the dependency:list plugin and analyzed its output manually.

Rough description of the process:The output of running this goal is a list of all transitive dependencies of all the projects in the project hierarchy. We than parse the output, sort the dependencies and search only for those artifacts that differ only by version id. This requires some scripting in your CI env but it is the only way for now to get the overall picture.




回答3:


you could run depenency report or use dependency tree:

mvn dependency:tree -Dverbose -Dincludes=commons-collections




回答4:


You could just have a look at your dependency hiercharchy overview. This won't warn you, but you can see if certain versions are discarded for newer versions of the same library.




回答5:


You can resolve the version conflict by excluding the non wanted version from the apropriate dependency. For example:

<dependency>
    <groupId>org.jclouds.driver</groupId>
    <artifactId>jclouds-sshj</artifactId>
    <version>${jclouds.version}</version>
    <exclusions>
      <exclusion>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-core</artifactId>
      </exclusion>
    </exclusions>
</dependency>

Or you add com.sun.jersey:jersey-core with the wanted version to your dependencies. Maven resolves version confilicts by supporting the dependency which is closest to the dependencies root.




回答6:


@Vitaly

my quickly hand-made command line to detect multiple versions of the same dependency :

mvn dependency:tree | grep ":compile" | sed 's/.* \(.*\):compile/\1/' | sort -u | cut -d ':' -f '1 2' | uniq -c | grep -vE "^ *1"

then, we can use the following command line to get used versions of theses dependencies (it isn't an optimized command line ;) : 

for dep in $(mvn dependency:tree | grep ":compile" | sed 's/.* \(.*\):compile/\1/' | sort -u | cut -d ':' -f '1 2' | uniq -c | grep -vE "^ *1" | cut -d ' ' -f 8); 
do 
  echo $dep; 
  mvn dependency:tree | grep $dep; 
  echo 
done


来源:https://stackoverflow.com/questions/9797334/maven-detect-multiple-versions-of-the-same-dependency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!