如何运行带有阴影依赖项的单元测试?

时间:2019-07-05 01:46:20

标签: java maven dependency-management

我遇到一个我不了解的Maven项目的测试失败。

maven项目被设置为一个多模块项目,并且它阴影了其依赖项之一(Google Guava,因为Spark本身对Google Guava的依赖项存在冲突)。

以下是父pom的简化版本:

<?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">
    ... other stuff...

    <modules>
        <module>module A</module>
        <module>module B</module>
        <module>module C</module>
        ...
    </modules>

    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.0-jre</version>
        </dependency>
        ...other dependencies

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <id>relocateGuava</id>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <relocations>
                                <relocation>
                                    <pattern>com.google</pattern>
                                    <shadedPattern>shaded.com.google</shadedPattern>
                                </relocation>
                            </relocations>
                        </configuration>
                    </execution>
                    <execution>
                        <id>buildUberJar</id>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>reference.conf</resource>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
        </plugins>
    </build>
</project>

失败包括:

Caused by: java.lang.ClassNotFoundException: shaded.com.google.common.collect.Multimap
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 22 more

,令人讨厌的行是模块A:import com.google.common.collect.ListMultimap;中的简单导入语句。

依赖关系结构如下: -模块B是测试失败的模块 -模块B将模块A命名为依赖项 -模块A包含该import语句

这是模块B的pom的简化版本:

<?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">
    <dependencies>
        <dependency>
            module A
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.7</version>
                <executions>
                    <execution>
                        <id>default-deploy</id>
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

认为可能发生的事情是在对模块B的依赖项进行着色之前运行了模块B的测试。因此,基本上,正在测试的模块B代码在类路径中不包括阴影依赖项。但是,B依赖于A,并且A的代码已被重写为指向阴影依赖项,而不是原始依赖项。因此,当B包含A的代码时,它包括指向阴影依赖项的代码,而这些阴影依赖项对B不可用。

问题: -那是怎么回事? -我该如何解决?

(如果您不知道,我对Java和Maven都没有经验)

编辑:还将添加mvn package成功-只有mvn test失败。

1 个答案:

答案 0 :(得分:0)

我认为您可能对谷歌番石榴的版本有误,可以尝试以下三种方式:

  1. 删除保存在本地maven存储库中的google-guave本地目录,然后重新导入项目的整个依赖项,几年前我曾经使用这种方法来解决问题。

  2. 执行模块A的maven安装,因此您可以在本地maven存储库中找到模块A,如果maven install获取模块A的错误,则模块A中一定有问题,因此我们可以排除模块B的问题

  3. 在模块B中明确定义google-guava依赖性,因此,当您运行测试用例时,maven将从模块B中获得google-guava依赖性,因此将覆盖项目对google-guava的依赖性。

如果以上三种方法都不适合您的探针,我希望您可以执行mvn dependency:list以及您实际获得的依赖项,在运行测试用例时,尤其要注意google-guava的Verion,请检查其版本是否正确在项目的pom.xml中正确定义