简体   繁体   English

在多模块Maven项目中临时解决依赖项

[英]Resolving dependencies ad-hoc in multi-module maven project

I have an multi-module project in maven, and when I run normal goals on it, everything works fine. 我在maven中有一个多模块项目,当我在其上运行正常目标时,一切正常。 For testing, I have an module mytest, and this module is run fine when I run mvn package in the parent directory. 为了进行测试,我有一个模块mytest,当我在父目录中运行mvn package时,该模块运行良好。

But for not compiling and running everything everytime, I would prefer to run the tests standalone, and to take the packaged files as the dependencies. 但是为了避免每次都编译和运行所有程序,我希望独立运行测试,并将打包的文件作为依赖项。 But if I try to do so using mvn test -Dtest=simpleTest in the test-submodule-directory, the tests are not run, because it can't find the dependencies. 但是,如果我尝试在test-submodule-directory中使用mvn test -Dtest = simpleTest这样做,则不会运行测试,因为它找不到依赖项。 After a mvn install in the parent-directory, it finds them, but uses the artifacts from the repository - a behaviour I do not want, because I have to run install everytime. 在父目录中进行mvn安装后,它会找到它们,但会使用存储库中的工件-这是我不希望的行为,因为我必须每次都运行install。 And if I try to run the tests from the parent directory with mvn test -Dtest=simpleTest, it does not find the tests in the other modules, and stops, or, if I add an project-list with -pl test, it just does not find the dependencies again. 而且,如果我尝试使用mvn test -Dtest = simpleTest从父目录运行测试,则它不会在其他模块中找到测试,然后停止,或者,如果我添加了带有-pl test的项目列表,它只是不再找到依赖项。

Is there any way to run a maven test in a specific submodule, that has dependencies for other submodules, without installing the submodules to the local repository? 是否可以在不将子模块安装到本地存储库的情况下,在具有其他子模块依赖性的特定子模块中运行Maven测试? It would be possible to archieve this by building the comand-line-call for the test onself, but that seems very time-consuming. 可以通过自行构建用于测试的命令来解决这个问题,但这似乎非常耗时。

/EDIT: /编辑:

To describe the problem more exactly, I'll add source of a minimal project. 为了更准确地描述问题,我将添加一个最小项目的源代码。

There is a parent pom: 有一个父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>

a Pom for the module that needs to be tested (in a real-world project, there would be more similiar modules): 需要测试的模块的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>

and a Pom for the modules that tests: 以及一个用于测试模块的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>

There are now two classes, one in datamodule/src/main/java: 现在有两个类,一个在datamodule / src / main / java中:

public class Thing{
    int i = 5;
}

and one in testmodule/src/test/java: 还有一个在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);
    }
}

When I now run mvn package in the parent folder, everything works fine. 现在,当我在父文件夹中运行mvn package时,一切正常。 But if I run mvn test in the testmodule folder, it crashes because it can't resolve the dependency to the datamodule. 但是,如果我在testmodule文件夹中运行mvn test ,则会崩溃,因为它无法解析对数据模块的依赖关系。 If I run mvn install in the parent folder before, it works - but takes the old installed version. 如果我以前在父文件夹中运行mvn install ,那么它可以工作-但使用的是旧版。

What I want is the ability to run the integration-test in the testmodule, without calling other tests or invoking the build-process of other parts. 我想要的是能够在testmodule中运行集成测试,而无需调用其他测试或调用其他部分的构建过程的能力。 Is there any possibility to do so? 有可能这样做吗?

/EDIT2: / EDIT2:

I found out when googling the issue, that one could have done that in maven 2 with the reactor plugin: Build single module from multimodule pom . 我在搜寻该问题时发现,可以在maven 2中使用Reactor插件做到这一点: 从multimodule pom构建单个模块 Anyways, this plugin is not used anymore ( http://maven.40175.n5.nabble.com/VOTE-Retire-Maven-Reactor-Plugin-td5789172.html ). 无论如何,不​​再使用此插件( http://maven.40175.n5.nabble.com/VOTE-Retire-Maven-Reactor-Plugin-td5789172.html )。 In fact, like proposed in the first answer, people say one could use profiles to do this: How do you perform a reactor build in Maven3 without a root project? 实际上,就像第一个答案中提出的那样,人们说人们可以使用配置文件来执行此操作: 如何在没有根项目的情况下在Maven3中执行反应堆构建?

But, when adding a profile like this: 但是,当添加这样的配置文件时:

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

And runnning it with mvn test -P onlyRunTests, still everything which comes before testing the testmodule (so compiling and running the datamodule) is executed. 并使用mvn test -P onlyRunTests运行它,仍然执行测试testmodule之前的所有操作(因此编译并运行datamodule)。 Unfortunately, this is the behaviour not wanted - I want to call integration tests, not the unit tests from the other modules. 不幸的是,这是不需要的行为-我想调用集成测试,而不是其他模块的单元测试。 So is there any way to do so? 那么有没有办法做到这一点?

/EDIT 3: There were two other promising ways to avoid this Problem: building with --pl eg --pl testmodule --also-make-dependencies. / EDIT 3:还有两种避免该问题的有前途的方法:使用--pl进行构建,例如--pl testmodule --also-make-dependencies。 This does not work either, it does not build the dependencies. 这也不起作用,也不会建立依赖关系。 The other way would be defining a path (with systemPath) of the depencies. 另一种方法是定义依赖关系的路径(使用systemPath)。 This does not work, as it only works with absolute paths, and this would make the pom unexecutable under all other systems. 这是行不通的,因为它仅适用于绝对路径,这将使pom在所有其他系统下均不可执行。

The problem in your build is (based on the example pom files) not a multi-module build cause if you have a multi-module build all your childs need to have a parent which is not the case. 您的构建中的问题是(基于示例pom文件)不是多模块构建的原因,如果您具有多模块构建,则所有孩子都需要拥有一个父母, 事实并非如此。 In your case you are having an aggregator which is not what you need. 在您的情况下,您拥有的聚合器不是您所需要的。

The test module should look like this: 测试模块应如下所示:

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

and your datamodule should look like this: 并且您的数据模块应如下所示:

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

Now if you look at the root and try mvn clean package you should see that the testmodule is build after the datamodule. 现在,如果您查看根目录并尝试使用mvn clean package ,则应该看到testmodule是在datamodule之后构建的。 This is needed as you already determined to let Maven calculate the build order of the artifacts. 因为您已经确定要让Maven计算工件的构建顺序,所以这是必需的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM