使用maven-shade-plugin时出现依赖冲突怎么办?

Mus*_*ice 6 dependencies maven maven-shade-plugin

我正在使用 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
Run Code Online (Sandbox Code Playgroud)

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

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

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

像上面这样的案例最终会被大量排除,这对这种做法提出了两个问题:

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

Ing*_*ngo 3

您是否尝试过使用DependencyConvergence 规则添加maven-enforcer-plugin?这对我来说与阴影插件结合使用效果很好。它会告诉您哪些工件引入了同一类的不同版本。它让我知道我必须排除什么。

        <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>
Run Code Online (Sandbox Code Playgroud)