Maven Shade Plugin вызывает дубликаты jar на пути к классам при запуске интеграционных тестов - PullRequest
0 голосов
/ 13 июня 2019

У меня есть проект, который включает зависимость S3 от Java v2 SDK AWS и создает затененный jar.Я нажимаю эту проблему при запуске моих интеграционных тестов с терминала.Проблема заключается в том, что перехватчики добавляются дважды, потому что путь к классам содержит два файла jar с файлом S3: один раз в моем затененном банке и один раз из локального хранилища .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 Ответ

1 голос
/ 14 июня 2019

Это связано с вашей конфигурацией 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>
...