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

时间:2013-09-18 10:01:25

标签: java maven jar war

我的Maven项目foo.web的源文件位于src/main,测试源位于src/test。当然,测试类使用“主”类。现在我想在运行时在另一个项目中使用测试类,所以我按照these instructions关于如何创建测试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>

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

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

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

<dependency>
        <groupId>foo</groupId>
        <artifactId>web</artifactId>
        <version>SNAPSHOT</version>
        <type>war</type>
        <scope>runtime</scope>
</dependency>

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

3 个答案:

答案 0 :(得分:4)

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

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

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

要启用此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>

由于类是附加,因此它们将由Maven与WAR工件一起安装和部署。请注意,这仅为您提供常规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>

答案 1 :(得分:1)

尝试:

<dependency>
    <groupId>foo</groupId>
    <artifactId>web</artifactId>
    <version>SNAPSHOT</version>
    <type>war</type>
    <classifier>tests</classifier>
    <scope>test</scope>
</dependency>

答案 2 :(得分:0)

Maven允许您对快照依赖性进行一些配置

<repository>
<id>foo-repository</id>
<url>...</url>
<snapshots>
    <enabled>true</enabled>
    <updatePolicy>XXX</updatePolicy>
</snapshots>

检查以上配置。如果pom.xml maven中的false不会更新快照。您还会发现以下主题对您的查询有用What exactly is a Maven Snapshot and why do we need it?