在多模块maven项目中ad-hoc解决依赖关系

时间:2014-03-22 14:24:41

标签: java maven

我在maven中有一个多模块项目,当我在其上运行正常目标时,一切正常。为了测试,我有一个模块mytest,当我在父目录中运行mvn包时,这个模块运行正常。

但是为了不每次都编译和运行所有内容,我宁愿独立运行测试,并将打包文件作为依赖项。但是如果我尝试在test-submodule目录中使用mvn test -Dtest = simpleTest来执行此操作,则不会运行测试,因为它无法找到依赖项。在父目录中安装mvn后,它会找到它们,但会使用存储库中的工件 - 这是我不想要的行为,因为我必须每次都运行安装。如果我尝试使用mvn test -Dtest = simpleTest从父目录运行测试,它在其他模块中找不到测试,并停止,或者,如果我使用-pl test添加项目列表,它只是没有找到依赖项。

有没有办法在特定的子模块中运行maven测试,该子模块具有其他子模块的依赖关系,而无需将子模块安装到本地存储库?有可能通过建立自己的测试命令行调用来实现这一点,但这似乎非常耗时。

/编辑:

为了更准确地描述问题,我将添加一个最小项目的来源。

有一个父母pom:

<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>minimalproject</groupId>
    <artifactId>minimalproject</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>minimalproject</name>

    <modules>
        <module>datamodule</module>
        <module>testmodule</module>
    </modules>
</project>

需要测试的模块的Pom(在实际项目中,会有更多类似的模块):

<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>minimalproject</groupId>
    <artifactId>datamodule</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>datamodule</name>
</project>

和测试模块的Pom:

<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>minimalproject</groupId>
    <artifactId>testmodule</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>testmodule</name>

    <dependencies>
        <dependency>
            <groupId>minimalproject</groupId>
            <artifactId>datamodule</artifactId>
            <version>0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit-dep</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

现在有两个类,一个在datamodule / src / main / java中:

public class Thing{
    int i = 5;
}

和testmodule / src / test / java中的一个:

import org.junit.Test;
import junit.framework.Assert;

public class MyTest{

    @Test
    public void testThing(){
        Thing t = new Thing();
        Assert.assertEquals(5, t.i);
    }
}

当我现在在父文件夹中运行mvn package时,一切正常。但是如果我在testmodule文件夹中运行mvn test,它会崩溃,因为它无法解析对数据模块的依赖性。如果我之前在父文件夹中运行mvn install,它可以工作 - 但是需要旧的安装版本。

我想要的是能够在testmodule中运行集成测试,而无需调用其他测试或调用其他部分的构建过程。有没有可能这样做?

/ EDIT2:

我在搜索问题时发现,人们可以在反应堆插件maven 2中做到这一点:Build single module from multimodule pom。无论如何,这个插件不再使用(http://maven.40175.n5.nabble.com/VOTE-Retire-Maven-Reactor-Plugin-td5789172.html)。事实上,就像在第一个答案中提出的那样,人们说可以使用配置文件来执行此操作:How do you perform a reactor build in Maven3 without a root project?

但是,在添加这样的个人资料时:

<profiles>
    <profile>
        <id>onlyRunTests</id>
        <modules>
            <module>testmodule</module>
        </modules>
    </profile>
</profiles>

使用mvn test -P onlyRunTests运行它,仍然执行测试testmodule(编译和运行数据模块)之前的所有内容。不幸的是,这是不想要的行为 - 我想调用集成测试,而不是其他模块的单元测试。有没有办法这样做?

/编辑3: 还有另外两种有希望的方法来避免这个问题:使用--pl构建--pl testmodule --also-make-dependencies。这也不起作用,它不构建依赖项。 另一种方法是定义依赖关系的路径(使用systemPath)。这不起作用,因为它只适用于绝对路径,这将使pom在所有其他系统下无法实现。

1 个答案:

答案 0 :(得分:1)

您的构建中的问题是(基于示例pom文件)而不是多模块构建原因如果您有多模块构建,则所有孩子都需要拥有的父级案子。在你的情况下,你有一个不是你需要的聚合器。

测试模块应如下所示:

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

    <parent>
      <groupId>minimalproject</groupId>
      <artifactId>minimalproject</artifactId>
      <version>0.1-SNAPSHOT</version>
    </parent>

    <artifactId>testmodule</artifactId>

    <name>testmodule</name>

    <dependencies>
        <dependency>
            <groupId>minimalproject</groupId>
            <artifactId>datamodule</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit-dep</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

你的数据模块应如下所示:

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

    <parent>
      <groupId>minimalproject</groupId>
      <artifactId>minimalproject</artifactId>
      <version>0.1-SNAPSHOT</version>
    </parent>

    <artifactId>datamodule</artifactId>

    <name>datamodule</name>
</project>

现在,如果您查看根并尝试mvn clean package,您应该会看到testmodule是在数据模块之后构建的。这是必需的,因为您已经决定让Maven计算工件的构建顺序。