现在,每个Maven模块都有自己的模块描述符(
module-info.java
),位于src/main/java
文件夹中。测试类没有模块描述符。然而,我遇到了一个问题,我一直无法解决,并且没有找到任何解决方法:
如何使用Maven和Java模块进行跨模块测试依赖?
在我的情况下,我有一个“common” Maven模块,其中包含一些接口和/或抽象类(但没有具体实现)。在同一个Maven模块中,我有抽象测试来确保这些接口/抽象类的实现行为正确。然后,有一个或多个子模块,其中包含接口/抽象类的实现以及扩展抽象测试的测试。
然而,在尝试执行Maven构建的
test
阶段时,子模块将失败,并显示:[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:testCompile (default-testCompile) on project my-impl-module: Compilation failure: Compilation failure:
[ERROR] C:\projects\com.example\my-module-test\my-impl-module\src\test\java\com\example\impl\FooImplTest.java:[4,25] error: cannot find symbol
[ERROR] symbol: class FooAbstractTest
[ERROR] location: package com.example.common
我怀疑这是因为测试不是模块的一部分导致的。即使Maven进行了某些“魔法”将测试执行在模块的范围内,它也无法解决我所依赖的模块中的测试问题(由于某种原因)。如何解决这个问题?
项目的结构如下(完整演示项目文件在此处可用):
├───my-common-module
│ ├───pom.xml
│ └───src
│ ├───main
│ │ └───java
│ │ ├───com
│ │ │ └───example
│ │ │ └───common
│ │ │ ├───AbstractFoo.java (abstract, implements Foo)
│ │ │ └───Foo.java (interface)
│ │ └───module-info.java (my.common.module: exports com.example.common)
│ └───test
│ └───java
│ └───com
│ └───example
│ └───common
│ └───FooAbstractTest.java (abstract class, tests Foo)
├───my-impl-module
│ ├───pom.xml
│ └───src
│ ├───main
│ │ └───java
│ │ ├───com
│ │ │ └───example
│ │ │ └───impl
│ │ │ └───FooImpl.java (extends AbstractFoo)
│ │ └───module-info.java (my.impl.module: requires my.common.module)
│ └───test
│ └───java
│ └───com
│ └───example
│ └───impl
│ └───FooImplTest.java (extends FooAbstractTest)
└───pom.xml
{{my-impl-module/pom.xml}}中的依赖关系如下:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-common-module</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-common-module</artifactId>
<classifier>tests</classifier> <!-- tried type:test-jar instead, same error -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
注意:上面只是我创建的一个项目,用于演示问题。真实项目要复杂得多,可以在这里找到(主分支尚未模块化),但原理相同。
PS:我认为代码本身没有问题,因为使用普通类路径(即在IntelliJ中或不带Java模块描述符的Maven中)编译和运行一切正常。问题是由Java模块和模块路径引入的。
my-common-module
中,然后在my-impl-module/pom.xml
的 my-common-module 依赖中将<classifier>tests</classifier>
改为<type>test-jar</type>
。我已经尝试过了,它可以正常工作。 - troig