Maven:在运行时使用 test-jar 时缺少依赖项

Ste*_*ler 1 java jar war maven

我的 Maven 项目foo.web的源文件src/mainsrc/test. 当然,测试类使用“主”类。现在我想在运行时在另一个项目中使用测试类,所以我按照这些关于如何创建测试 jar 的说明进行操作。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <executions>
        <execution>
            <goals> 
                <goal>test-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

这非常有效,web-SNAPSHOT-tests.jar创建了一个 jar ,我可以将它包含在我的其他项目中。

<dependency>
        <groupId>foo</groupId>
        <artifactId>web</artifactId>
        <version>SNAPSHOT</version>
        <type>test-jar</type>
</dependency>
Run Code Online (Sandbox Code Playgroud)

但似乎对 的依赖web-SNAPSHOT没有正确设置,因为在运行时我收到foo.web. 所以我添加了另一个依赖项:

<dependency>
        <groupId>foo</groupId>
        <artifactId>web</artifactId>
        <version>SNAPSHOT</version>
        <type>war</type>
        <scope>runtime</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)

不幸的是,这没有任何改变。有谁知道这里有什么问题?

小智 5

WAR 档案的结构与 JAR 不同。在 Tomcat 或 JBoss 等应用服务器中运行时,服务器将正确处理 WAR。由于您在服务器外部运行,因此工件将像普通 JAR 存档一样使用。因为 WAR 对.class文件使用不同的位置,所以NoClassDefFoundError会在运行时抛出。

在 JAR 中,类com.example.Foo将存储在/com/example/Foo.class. 由于 WAR 旨在包含库、资源等,因此类不应相对于存档的根进行存储。相反,它们包含在文件夹中/WEB-INF/classesFoo将存储为/WEB-INF/classes/com/example/Foo.class.

幸运的是,Maven 开发人员想到了这个问题,并attachClasses在 WAR 插件中添加了该选项。此选项使用classes仅包含 JAR 格式的 Java 类(相对于存档根)的分类器创建一个额外的 JAR 。

要启用此 JAR 的构建,您可以在 WAR 项目的build部分中使用此代码段(除了用于maven-jar-plugin构建测试 JAR的配置之外):

<pluginManagement>
    <plugins>
        <!-- … -->

        <plugin>
            <!-- build the classes JAR (non-test classes) -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <attachClasses>true</attachClasses>
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>

<plugins>
    <!-- … -->

    <plugin>
        <!-- build the test JAR (test classes) -->
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.4</version>
        <executions>
            <execution>
                <goals> 
                    <goal>test-jar</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>
Run Code Online (Sandbox Code Playgroud)

由于这些类是附加的,它们将与 WAR 工件一起由 Maven 安装和部署。请注意,这仅为您提供常规 WAR 存档的内容,要使用测试类,您需要依赖于类工件和测试 jar。为此,您可以使用:

<dependencies>
    <!-- … -->

    <dependency>
        <!-- test classes only -->
        <groupId>foo</groupId>
        <artifactId>web</artifactId>
        <version>SNAPSHOT</version>
        <type>test-jar</type>
    </dependency>

    <dependency>
        <!-- non-test classes only -->
        <groupId>foo</groupId>
        <artifactId>web</artifactId>
        <version>SNAPSHOT</version>
        <type>jar</type>
        <classifier>classes</classifier>
        <scope>runtime</scope>
    </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)