Maven Shade Plugin 在运行集成测试时导致类路径上出现重复的 jars [英] Maven Shade Plugin causes duplicate jars on classpath when running integration tests

查看:107
本文介绍了Maven Shade Plugin 在运行集成测试时导致类路径上出现重复的 jars的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个项目,其中包含来自 AWS 的 Java v2 SDK 并构建一个带阴影的罐子.我在运行我的集成测试时遇到了这个问题终端.问题是拦截器添加了两次,因为类路径包含两个带有 S3 jar 的 jar:一次在我的阴影 jar 中,一次来自本地 .m2 存储库.不幸的是,我无法控制包含此问题的代码,因此我需要找到解决方法,直到问题得到解决.

I have a project which includes the S3 dependency from AWS's Java v2 SDK and builds a shaded jar. I am hitting this problem when running my integration tests from the terminal. The problem is that the interceptors are added twice because the classpath contains two jars with the S3 jar: once in my shaded jar and once from the local .m2 repository. Unfortunately I don't have any control of the code that contains this issue so I need to find a workaround until the issue is fixed.

我已经用以下 pom 和测试类复制了这个问题:

I have replicated the problem with the following pom and test class:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.stu</groupId>
    <artifactId>duplicate-jars-classpath</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <aws.sdk.version>2.5.62</aws.sdk.version>
        <junit.version>5.4.2</junit.version>
        <maven.failsafe.plugin.version>2.22.0</maven.failsafe.plugin.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-engine</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <id>run-tests</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

测试类 - src/test/java/com/stu/S3DuplicateJarTest.java

Test class - src/test/java/com/stu/S3DuplicateJarTest.java

package com.stu;

import java.util.Collections;

import org.junit.jupiter.api.Test;

import software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory;

public class S3DuplicateJarTest {

    @Test
    void check_for_duplicate_jars() throws Exception {
        System.out.println("********** AWS execution interceptors:");
        Collections.list(
                new ClasspathInterceptorChainFactory().getClass().getClassLoader()
                        .getResources("software/amazon/awssdk/services/s3/execution.interceptors")
        ).forEach(System.out::println);
    }
}

如果我在 IDE 中运行测试,则输出如下:

If I run the tests in my IDE then this is the output:

********** AWS execution interceptors:
jar:file:/Users/<name>/.m2/repository/software/amazon/awssdk/s3/2.5.48/s3-2.5.48.jar!/software/amazon/awssdk/services/s3/execution.interceptors

从终端这是运行 mvn clean verify 时的输出:

From the terminal this is the output when running mvn clean verify:

[INFO] Running com.stu.S3DuplicateJarTest
********** AWS execution interceptors:
jar:file:/Users/<name>/Development/duplicate-jars-classpath/target/duplicate-jars-classpath-1.0-SNAPSHOT.jar!/software/amazon/awssdk/services/s3/execution.interceptors
jar:file:/Users/<name>/.m2/repository/software/amazon/awssdk/s3/2.5.62/s3-2.5.62.jar!/software/amazon/awssdk/services/s3/execution.interceptors

如您所见,终端已找到与路径匹配的两个资源.

As you can see the terminal has found two resources matching the path.

我能做些什么来避免这种情况?我的配置有问题吗?

Is there anything I can do to avoid this? Is there something wrong with my configuration?

推荐答案

由于您的 maven 配置,shade 插件将所有依赖项打包到一个 jar 文件中.

It's due to your maven configuration, shade plugin packs all dependencies into a single jar file.

您的 failsafe 插件使用来自项目依赖项 (.m2/...) 和单个 jar 文件的类路径运行测试,因此存在重复的资源.

Your failsafe plugin runs tests using class path from both the project dependencies (.m2/...) and that single jar file, hence the duplicated resources.

这似乎只有在命令行中使用 failsafe 时才会发生.而且很容易绕过,您可以简单地告诉 failsafe 不加载该依赖项.(无论如何它都可以在那个单个 jar 文件中使用)

This seems to be only happening when using failsafe in command line, though. And it's fairly easy to get around, you can simply tell failsafe to not load that dependency. (It'll be available in that single jar file anyway)

  <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-failsafe-plugin</artifactId>
      <version>${maven.failsafe.plugin.version}</version>
      <configuration>
          <includes>
              <include>**/*Test.java</include>
          </includes>
          <classpathDependencyExcludes>
              <classpathDependencyExcludes>software.amazon.awssdk:s3</classpathDependencyExcludes>
          </classpathDependencyExcludes>
      </configuration>
      <executions>
          <execution>
              <id>run-tests</id>
              <phase>integration-test</phase>
              <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
              </goals>
          </execution>
      </executions>
  </plugin>

这篇关于Maven Shade Plugin 在运行集成测试时导致类路径上出现重复的 jars的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆