使用maven-shade-plugin时,我应该怎么做依赖冲突?

时间:2016-02-10 15:41:02

标签: maven dependencies maven-shade-plugin

我使用maven-shade-plugin创建一个包含我所有项目依赖项的可执行jar。有时候,这些依赖关系带来了自己的依赖关系,与其他库的依赖关系发生冲突,而maven-shade-plugin警告我,它不确定在超级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来确保我排除了较低版本的违规依赖项,希望最新版本是最成熟且无bug的。

如上所述的案例最终会出现大量例外情况,这引发了两个关于这种做法的问题:

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

1 个答案:

答案 0 :(得分:2)

您是否尝试使用maven-enforcer-plugin添加DependencyConvergence 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>