Can';不能让Maven测试范围的依赖关系与Java9(NOR10)模块一起工作
编辑: 我分析了给出的答案。特别是我检验了直到Brychcy的假设,这个假设似乎成立,但提出了更多的问题。 我在问题末尾添加了分析,在以下大分隔符之后: “------蒂尔·布莱奇西回答的分析------” 不知何故,它在IJ中编译和运行,但是Can';不能让Maven测试范围的依赖关系与Java9(NOR10)模块一起工作,java,maven,java-9,java-10,Java,Maven,Java 9,Java 10,编辑: 我分析了给出的答案。特别是我检验了直到Brychcy的假设,这个假设似乎成立,但提出了更多的问题。 我在问题末尾添加了分析,在以下大分隔符之后: “------蒂尔·布莱奇西回答的分析------” 不知何故,它在IJ中编译和运行,但是mvn clean install无法编译测试 2个模块的说明,以及出现故障的原因 我有一个Java9Maven项目,包含两个模块:apimod和clientmod。 模块clientmod依赖于模块apimod(这些模块都是Maven模块和Java 9模
mvn clean install
无法编译测试
2个模块的说明,以及出现故障的原因
我有一个Java9Maven项目,包含两个模块:apimod
和clientmod
。
模块clientmod
依赖于模块apimod
(这些模块都是Maven模块和Java 9模块)
另外,我希望模块clientmod
不仅能够重用apimod
中的生产代码,还能够重用测试代码。
这是一种常见的模式,我在Java8中使用过很多次。
对于Java9(与Java10相同),只要我不声明module info.Java
(也就是说,只要我不使用模块系统运行),它也可以正常工作
但一旦我这样做,启用测试依赖项似乎就禁用了生产依赖项:api.Base
(模块apimod
的src/main
类)从client.test.DerivedTest
(模块clientmod
的src/test
类)中不再可见。测试不再编译
这是Maven中的bug还是Java9中的bug?这是最新的版本:Java9.0.4(与Java10相同)、Maven 3.5.3、Maven编译器插件3.7.0
我目前的分析
代码
源代码位于:
git clone https://github.com/vandekeiser/wires.git
我将分支测试失败的问题“二分法”:
git checkout MINIMIZE_ISSUE
`mvn clean install`
->构建失败(测试clientmod
时出现编译错误)
Maven测试范围依赖项
我希望模块clientmod
不仅能够重用apimod
中的生产代码,而且能够重用测试代码。对于Maven,您可以这样做(clientmod/pom.xml
):
尝试启用两个模块系统时出现故障
对于Java 9,如果我同时声明测试范围的依赖项和Java 9模块,测试将不再编译(mvn clean install
output):
用javac重现问题:模块修补中的一个bug?
这就好像启用测试依赖项(src/test
)会禁用生产依赖项(src/main
)。我知道在这个场景中,Maven应该使用javac--patch module
标志。
因此,我仅使用javac(使用mvn-X的调试输出)重现了这个问题:
相同的编译,跳过Maven:
javac "G:\projets\wires\wires\wires\clientmod\src\test\java\client\test\DerivedTest.java" \
-d "G:\projets\wires\wires\wires\clientmod\target\test-classes" \
-classpath "G:\projets\wires\wires\wires\clientmod\target\test-classes;" \
--module-path "G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT-tests.jar;G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT.jar;" \
-sourcepath "G:\projets\wires\wires\wires\clientmod\src\test\java;" \
--release 9 \
-Xlint:all \
--patch-module clientmod="G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\clientmod\src\test\java;"
相同的编译错误:
G:\projets\wires\wires\wires\clientmod\src\test\java\client test\DerivedTest.java:8: error: cannot access Base
new Derived().equals(null); ^
class file for api.Base not found
1 error
我试图使用javac标志来禁用模块系统,但它们似乎不存在于我的64位Windows Oracle JVM中?(Java HotSpot(TM)64位服务器虚拟机(构建9.0.4+11,混合模式):
添加(逻辑上不需要,在绝望中完成)导出或读取也不会改变任何内容:
--add-reads apimod=ALL-UNNAMED \
--add-reads clientmod=ALL-UNNAMED \
--add-exports apimod/api=ALL-UNNAMED \
--add-exports clientmod/client=ALL-UNNAMED \
mvn的输出-版本:
Apache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-24T20:49:05+01:00)
Maven home: G:\software\apache-maven-3.5.3
Java version: 9.0.4, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk-9.0.4
Default locale: fr_FR, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
蒂尔·布里奇西的回答分析
感谢您的详细回答,本质上是“maven似乎还不支持这个用例”
-->因此,让我们试着在没有maven的情况下重现这个问题。我为这些试验创建了分支try\u ADAPT\u khmarbaise-MINIMIZE\u issue
(很抱歉分支名称混乱)
修改maven记录的以前的命令行,即:
javac "G:\projets\wires\wires\wires\clientmod\src\test\java\client\test\DerivedTest.java"
-d "G:\projets\wires\wires\wires\clientmod\target\test-classes"
-classpath "G:\projets\wires\wires\wires\clientmod\target\test-classes;"
--module-path "G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT-tests.jar;G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT.jar;"
-sourcepath "G:\projets\wires\wires\wires\clientmod\src\test\java;"
--release 9
-Xlint:all
--patch-module clientmod="G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\clientmod\src\test\java;"
--add-reads apimod=ALL-UNNAMED
--add-reads clientmod=ALL-UNNAMED
--add-exports apimod/api=ALL-UNNAMED
--add-exports clientmod/client=ALL-UNNAMED
--add-modules apimod
我从--模块路径中删除G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT-tests.jar;
我将其添加到——patch module clientmod
,得到:
javac "G:\projets\wires\wires\wires\clientmod\src\test\java\client\test\DerivedTest.java" \
-d "G:\projets\wires\wires\wires\clientmod\target\test-classes" \
-classpath "G:\projets\wires\wires\wires\clientmod\target\test-classes;" \
--module-path "G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT.jar;" \
-sourcepath "G:\projets\wires\wires\wires\clientmod\src\test\java;" \
--release 9 \
-Xlint:all \
--patch-module clientmod="G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\clientmod\src\test\java;G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT-tests.jar;" \
--add-reads apimod=ALL-UNNAMED \
--add-reads clientmod=ALL-UNNAMED \
--add-exports apimod/api=ALL-UNNAMED \
--add-exports clientmod/client=ALL-UNNAMED \
--add-modules apimod
-->好了,它现在可以编译了!所以你的假设maven编译器插件,或者说maven,不支持这一点,似乎已经得到了验证。
但是我认为我使用的最新版本应该支持它。我不知道从哪里开始检查
无论如何,同时,我尝试显式配置maven编译器插件,但没有效果。
我尝试过的一般结构是(maven-compiler-plugin.version=3.7.0):
2:
--模块源路径=../*/src/main/java;/*/src/test/java/;
--源路径=/G/projets/wires/wires/wires/wires/apimod/src/main/java;/G/projets/wires/wires/wires/wires/apimod/src/test/java;/G/projets/wires/wires/wires/clientmod/src/main/java;
-Xlint:全部
--补丁模块=clientmod=/G/projets/wires/wires/wires/clientmod/target/classes;/G/projets/wires/wires/wires/clientmod/src/test/java;/G/projets/wires/apimod/1.0-SNAPSHOT.jar;/G/projets/wires/wires/wires/wires/apimod/1.0-SNAPSHOT-tests.jar;
--add reads=apimod=ALL-UNNAME
--add reads=clientmod=ALL-UNNAMED
--添加导出=apimod/api=ALL-UNNAMED
--添加导出=clientmod/client=ALL-UNNAMED
--添加模块=apimod
看起来maven还不支持这个用例
问题在于apimod-1.0-SNAPSHOT-tests.jar
被视为自动模块,其自动模块名(从文件名派生)为“apimod
”,因此apimod-1.0-SNAPSHOT.jar
中的实际模块apimod
(稍后出现在模块路径上)被忽略
Maven应该检测到apimod-1.0-SNAPSHOT-tests.jar
属于apimod
,并使用--补丁模块apimod=G:\projets\wires\wires\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT-tests.jar
而不是将其作为--模块路径的一部分,它现在就可以工作了!这里已经解释了:
问题是名称冲突:将maven模块的名称更改为与java模块不同的名称,在problem reduction分支和main dev分支中修复了它
我仍然有一个警告(见链接),现在我忽略它,但它需要去
----
--add-reads apimod=ALL-UNNAMED \
--add-reads clientmod=ALL-UNNAMED \
--add-exports apimod/api=ALL-UNNAMED \
--add-exports clientmod/client=ALL-UNNAMED \
Apache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-24T20:49:05+01:00)
Maven home: G:\software\apache-maven-3.5.3
Java version: 9.0.4, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk-9.0.4
Default locale: fr_FR, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
javac "G:\projets\wires\wires\wires\clientmod\src\test\java\client\test\DerivedTest.java"
-d "G:\projets\wires\wires\wires\clientmod\target\test-classes"
-classpath "G:\projets\wires\wires\wires\clientmod\target\test-classes;"
--module-path "G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT-tests.jar;G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT.jar;"
-sourcepath "G:\projets\wires\wires\wires\clientmod\src\test\java;"
--release 9
-Xlint:all
--patch-module clientmod="G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\clientmod\src\test\java;"
--add-reads apimod=ALL-UNNAMED
--add-reads clientmod=ALL-UNNAMED
--add-exports apimod/api=ALL-UNNAMED
--add-exports clientmod/client=ALL-UNNAMED
--add-modules apimod
javac "G:\projets\wires\wires\wires\clientmod\src\test\java\client\test\DerivedTest.java" \
-d "G:\projets\wires\wires\wires\clientmod\target\test-classes" \
-classpath "G:\projets\wires\wires\wires\clientmod\target\test-classes;" \
--module-path "G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT.jar;" \
-sourcepath "G:\projets\wires\wires\wires\clientmod\src\test\java;" \
--release 9 \
-Xlint:all \
--patch-module clientmod="G:\projets\wires\wires\wires\clientmod\target\classes;G:\projets\wires\wires\wires\clientmod\src\test\java;G:\projets\wires\wires\wires\apimod\target\apimod-1.0-SNAPSHOT-tests.jar;" \
--add-reads apimod=ALL-UNNAMED \
--add-reads clientmod=ALL-UNNAMED \
--add-exports apimod/api=ALL-UNNAMED \
--add-exports clientmod/client=ALL-UNNAMED \
--add-modules apimod
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<release>${java.version}</release>
<compilerArgs>
[...]
</compilerArgs>
</configuration>
</plugin>
<!--1. Syntaxically OK, but:-->
<!--[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile (default-compile) on project apimod: Compilation failure: Compilation failure:-->
<!--[ERROR] /G:/projets/wires/wires/wires/apimod/src/main/java/api/Base.java:[1,1]-->
<!--file should be on source path, or on patch path for module-->
<!--[ERROR] /G:/projets/wires/wires/wires/apimod/src/main/java/module-info.java:[1,1]-->
<!--file should be on source path, or on patch path for module-->
<compilerArgs>
<arg>--class-path=/G/projets/wires/wires/wires/clientmod/target/test-classes;</arg>
<arg>
--module-path=/G/projets/wires/wires/wires/clientmod/target/classes;/G/projets/wires/wires/wires/apimod/target/apimod-1.0-SNAPSHOT.jar;
</arg>
<arg>--source-path=/G/projets/wires/wires/wires/clientmod/src/test/java;</arg>
<arg>-Xlint:all</arg>
<arg>
--patch-module=clientmod=/G/projets/wires/wires/wires/clientmod/target/classes;/G/projets/wires/wires/wires/clientmod/src/test/java;/G/projets/wires/wires/wires/apimod/target/apimod-1.0-SNAPSHOT-tests.jar;
</arg>
<arg>--add-reads=apimod=ALL-UNNAMED</arg>
<arg>--add-reads=clientmod=ALL-UNNAMED</arg>
<arg>--add-exports=apimod/api=ALL-UNNAMED</arg>
<arg>--add-exports=clientmod/client=ALL-UNNAMED</arg>
<arg>--add-modules=apimod</arg>
</compilerArgs>
<!--2.-->
<!--[ERROR] Please refer to dump files (if any exist) [date]-jvmRun[N].dump, [date].dumpstream and [date]-jvmRun[N].dumpstream.-->
<!--[ERROR] There was an error in the forked process-->
<!--[ERROR] api/foo/BaseTest (wrong name: apimod/api/foo/BaseTest)-->
<!--[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process-->
<!--[ERROR] api/foo/BaseTest (wrong name: apimod/api/foo/BaseTest)-->
<!--[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:673)-->
<compilerArgs>
<arg>--module-source-path=./*/src/main/java;./*/src/test/java/;</arg>
<arg>
--source-path=/G/projets/wires/wires/wires/apimod/src/main/java;/G/projets/wires/wires/wires/apimod/src/test/java;/G/projets/wires/wires/wires/clientmod/src/test/java;/G/projets/wires/wires/wires/clientmod/src/main/java;
</arg>
<arg>-Xlint:all</arg>
<arg>
--patch-module=clientmod=/G/projets/wires/wires/wires/clientmod/target/classes;/G/projets/wires/wires/wires/clientmod/src/test/java;/G/projets/wires/wires/wires/apimod/target/apimod-1.0-SNAPSHOT.jar;/G/projets/wires/wires/wires/apimod/target/apimod-1.0-SNAPSHOT-tests.jar;
</arg>
<arg>--add-reads=apimod=ALL-UNNAMED</arg>
<arg>--add-reads=clientmod=ALL-UNNAMED</arg>
<arg>--add-exports=apimod/api=ALL-UNNAMED</arg>
<arg>--add-exports=clientmod/client=ALL-UNNAMED</arg>
<arg>--add-modules=apimod</arg>
</compilerArgs>
[WARNING] COMPILATION WARNING :
[INFO] -------------------------------------------------------------
[WARNING] /G:/projets/wires/wires/wires/wires-core/src/test/java/fr/cla/wires/core/MavenVsJavaModulesReproduceTest.java:[9,54] class fr.cla.wires.support.oo.ddd.AbstractValueObjectTest in module is not exported
[INFO] 1 warning
[INFO] -------------------------------------------------------------
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /G:/projets/wires/wires/wires/wires-core/src/test/java/fr/cla/wires/core/MavenVsJavaModulesReproduceTest.java: warnings found and -Werror specified
[INFO] 1 error