Maven Shade插件在运行集成测试时在类路径上导致重复的jar

时间:2019-06-13 19:53:47

标签: java amazon-web-services maven maven-shade-plugin maven-failsafe-plugin

我有一个项目,该项目包括AWS's Java v2 SDK中的S3依赖关系,并构建了一个有阴影的jar。从终端运行集成测试时,我遇到了this problem。问题在于拦截器被添加了两次,因为类路径包含两个带有S3 jar的jar:一次位于我的着色jar中,一次来自本地.m2存储库。不幸的是,我对包含此问题的代码没有任何控制,因此我需要找到一种解决方法,直到问题解决。

我用以下pom和测试类复制了该问题:

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

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中运行测试,则输出为:

********** 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时,这是输出:

[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

您可以看到终端找到了两个与路径匹配的资源。

有什么办法可以避免这种情况?我的配置有问题吗?

1 个答案:

答案 0 :(得分:1)

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

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

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

  <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>