【问题标题】:What should I do about dependency conflicts when using the maven-shade-plugin?使用 maven-shade-plugin 时依赖冲突怎么办?
【发布时间】:2016-05-21 01:27:37
【问题描述】:

我正在使用 maven-shade-plugin 创建一个可执行 jar,其中包含我项目的所有依赖项。有时,这些依赖项会引入它们自己的依赖项,这些依赖项会与其他库的依赖项发生冲突,并且 maven-shade-plugin 会警告我不确定要在 uber jar 中包含哪个版本。

[WARNING] maven-shade-plugin has detected that some .class files
[WARNING] are present in two or more JARs. When this happens, only
[WARNING] one single version of the class is copied in the uberjar.
[WARNING] Usually this is not harmful and you can skeep these
[WARNING] warnings, otherwise try to manually exclude artifacts
[WARNING] based on mvn dependency:tree -Ddetail=true and the above
[WARNING] output

一般来说,我对这个警告的回应是在我的 pom 文件中使用依赖声明的 <exclusions> 元素来从我的项目中删除有问题的依赖项:

<!-- Amazon ElastiCache Client -->
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>elasticache-java-cluster-client</artifactId>
    <version>1.0.61.0</version>
    <exclusions>
        <!-- this junit dependency clashes with our test-scoped one and causes integration tests to fail to run -->
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit-dep</artifactId>
        </exclusion>
        <!-- this dependency brings in two versions of cglib that clash with one another -->
        <exclusion>
            <groupId>jmock</groupId>
            <artifactId>jmock-cglib</artifactId>
        </exclusion>
        <!-- newer versions of these dependencies come with dropwizard-core -->
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
</dependency>

当我这样做时,我使用mvn dependency:tree 来确保我排除了有问题的依赖项的低版本,希望最新版本是最成熟且没有错误的。

像上面这样的案例最终被排除在外,这引发了关于这种做法的两个问题:

  1. 在上面的示例中,为什么我必须手动排除 junit 和 jmock?这两个依赖项在the elasticache-java-cluster-client pom.xml 中都标记为&lt;scope&gt;test&lt;/scope&gt;,所以我希望它们不会包含在我从maven 获得的jar 中。
  2. 虽然我始终采用较新版本的依赖项的做法到目前为止似乎已经奏效,但我担心有一天我会破坏某些东西。有没有更好的方法来确定要保留哪个版本的依赖项?

【问题讨论】:

  • 您好,能否提供您使用的插件版本。一般来说,它不会添加标有范围测试的库。是否有任何情况下其中一些没有在您的 pom 中标记为范围测试?依赖部分的排除机制适用于解决依赖关系的 Maven 反应器,而不是阴影插件。因此,通过在依赖项中定义排除项,您只需向 Maven 指示要考虑哪些依赖项,哪些不考虑。另一方面,如果你想控制(过滤)阴影插件的依赖和包含,你需要在插件上提供配置
  • 查看 here 了解阴影插件配置
  • 我正在使用 2.3 版的 maven-shade-plugin。我熟悉 maven-shade-plugin 配置,并且已经按照您链接的页面上的建议进行了设置。我的问题是人们在选择要添加的排除项时通常采取的策略,而不是首先如何添加排除项。

标签: maven dependencies maven-shade-plugin


【解决方案1】:

您是否尝试过将maven-enforcer-pluginDependencyConvergence rule 添加?与阴影插件结合使用对我来说效果很好。它会告诉您哪些工件引入了相同类的不同版本。它使我能够找出我必须排除的内容。

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

【讨论】:

  • 中肯的建议,但对于现实世界来说可能过于严格。例如,我的项目依赖于ru.vyarus:dropwizard-guicey:3.1.1,它又出现了依赖收敛错误——它的一个依赖又依赖于com.google.inject:guice:3.0,而另外两个依赖于com.google.inject:guice:4.0。 Maven 排除项不允许我指定要包含的内容的哪个版本,所以我不知道如何解决这个问题。
猜你喜欢
  • 2011-03-12
  • 2013-06-24
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 2014-09-09
  • 2013-07-20
相关资源
最近更新 更多