有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java maven依赖插件忽略依赖版本?

在我看来,maven依赖插件在计算依赖列表时表现不好

假设这3个项目:

基准1:

<?xml version="1.0" encoding="UTF-8"?>                                                                                                                            
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>mygroup</groupId>
    <artifactId>base1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
      <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.3</version>
      </dependency>
    </dependencies>
</project>

基础2:

<?xml version="1.0" encoding="UTF-8"?>                                                                                                                            
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>mygroup</groupId>
    <artifactId>base2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
      <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
      </dependency>
    </dependencies>
</project>

合并:

<?xml version="1.0" encoding="UTF-8"?>                                                                                                                            
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>mygroup</groupId>
    <artifactId>combined</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
      <dependency>
        <groupId>mygroup</groupId>
        <artifactId>base1</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>mygroup</groupId>
        <artifactId>base2</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
    </dependencies>
</project>

base1和base2都依赖于commons lang,但每个版本都不同! 组合取决于base1和base2

在combined上调用mvn dependency:list时,我希望在版本2.3和2.6中看到base1、base2和commons lang,因为它们都被使用。 然而,实际产出是:

[INFO] The following files have been resolved:
[INFO]    commons-lang:commons-lang:jar:2.3:compile
[INFO]    mygroup:base1:jar:1.0-SNAPSHOT:compile
[INFO]    mygroup:base2:jar:1.0-SNAPSHOT:compile

它甚至没有使用版本号最高的公共语言,而是使用它最先找到的语言

我怎样才能避免这种情况?我需要所有依赖项


共 (3) 个答案

  1. # 1 楼答案

    根据此{a1}(相关部分以粗体突出显示):

    Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.

    因此,Maven选择版本2.3,因为它是在依赖项解析过程中首先遇到的。请注意,如果在combined模块上运行mvn dependency:tree,它将显示使用了哪个版本以及省略了哪个版本

    最好的解决方案是在combined工件中显式选择所需的版本,方法是在其POM中声明依赖项,以便Maven优先于其他版本:

    <?xml version="1.0" encoding="UTF-8"?>
    <project>
       <modelVersion>4.0.0</modelVersion>
       <groupId>mygroup</groupId>
       <artifactId>combined</artifactId>
       <version>1.0-SNAPSHOT</version>
       <packaging>jar</packaging>
    
       <dependencies>
         <dependency>
           <groupId>mygroup</groupId>
           <artifactId>base1</artifactId>
           <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
           <groupId>mygroup</groupId>
           <artifactId>base2</artifactId>
           <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>    <!  This will override the versions in base1 and base2  >
           <groupId>commons-lang</groupId>
           <artifactId>commons-lang</artifactId>
           <version>2.6</version>
         </dependency>
       </dependencies>
    

    请注意,Maven不能选择两个版本,因为在这种情况下,项目的类路径上会有相同类的两个定义,这可能导致运行时出现意外问题

  2. # 2 楼答案

    Maven从上到下扫描pom,并使用它遇到的第一个版本

    假设您确实需要这两个版本的commons-lang,您可以将这两个版本放在您的项目中,并使用maven将它们打包到您的jar中

    然而,编译器如何知道对StringUtils.isEmpty()的调用是调用版本2.3还是2.6

    Same discussion here