Can';不能让Maven测试范围的依赖关系与Java9(NOR10)模块一起工作

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模

编辑: 我分析了给出的答案。特别是我检验了直到Brychcy的假设,这个假设似乎成立,但提出了更多的问题。 我在问题末尾添加了分析,在以下大分隔符之后: “------蒂尔·布莱奇西回答的分析------”

不知何故,它在IJ中编译和运行,但是
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