在JMPS模块化应用程序中运行Spring Boot测试代码时出错

问题描述

我正在尝试使用Java 9中引入的JMPS创建模块化Spring Boot示例。

当前,我为测试工作创建了一个独立的Maven模块。

module greeting.webapp.test {
    requires greeting.webapp;
    requires spring.test;
    requires spring.boot;
    requires spring.web;
    requires spring.boot.starter.webflux;
    requires spring.boot.starter.test;
    requires spring.boot.test;
    requires spring.boot.test.autoconfigure;
    requires org.junit.jupiter;
    requires org.junit.jupiter.api;
    requires org.junit.jupiter.params;
    requires org.junit.jupiter.engine;
    requires org.junit.platform.commons;
    requires org.assertj.core;
    requires mockito.junit.jupiter;
}

运行sample test时,出现以下错误

Exception in thread "main" java.lang.IllegalAccessError: class org.junit.platform.launcher.TestIdentifier (in unnamed module @0x6325a3ee) cannot access class org.junit.platform.commons.util.Preconditions (in module org.junit.platform.commons) because module org.junit.platform.commons does not export org.junit.platform.commons.util to unnamed module @0x6325a3ee
    at org.junit.platform.launcher.TestIdentifier.from(TestIdentifier.java:56)
    at com.intellij.junit5.junit5IdeaTestRunner.<clinit>(junit5IdeaTestRunner.java:86)
    at java.base/java.lang.class.forName0(Native Method)
    at java.base/java.lang.class.forName(Class.java:377)
    at com.intellij.rt.junit.JUnitStarter.getAgentClass(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:210)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)

在测试模块中,我必须移动受测试作用域的deps来编译时间以使其在jmps中工作,如何解决此问题?

解决方法

恕我直言,没有简单的方法,或者根本没有好的方法。

您遇到的问题是尚未配置maven surefire correctly。您可以尝试一下-我确实做了,但不幸的是,但是我没有花太多时间使它起作用(我也不认为这会起作用,但这是一个不同的问题)。相反,我通过以下方式手动配置了surefire插件:

            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
                <argLine>
                    --add-exports org.junit.platform.commons/org.junit.platform.commons.util=ALL-UNNAMED
                    --add-exports org.junit.platform.commons/org.junit.platform.commons.logging=ALL-UNNAMED
                </argLine>
            </configuration>
        </plugin>

总体而言,我更喜欢gradle方法。您可以阅读我对here的经验。我也认为IDE(在我的案例中为Intellij)还没有适当的支持来运行单个(基于Maven的项目)测试,这与gradle不同。但是,公平地讲,到目前为止,我只尝试过针对您的回购交易...

您还可以了解gradle在需要使用其专用插件声明模块here时采用的一种相当巧妙的方法。