简体   繁体   English

如何让 JUnit5 与 JDK10(拼图)和 Maven3 一起工作?

[英]How to get JUnit5 with JDK10 (jigsaw) and Maven3 to work?

I work with some friends on a jdk 10 application which use the jigsaw feature set (introduced in jdk9) and junit5 with maven as build-management.我和一些朋友一起开发 jdk 10 应用程序,该应用程序使用 jdk 功能集(在 jdk9 中引入)和 junit5 与 maven 作为构建管理。

But always if we try to run tests with Maven we get a InaccessibleObjectException exception like:但总是如果我们尝试使用 Maven 运行测试,我们会得到一个 InaccessibleObjectException 异常,例如:

[ERROR] resourceSchedule  Time elapsed: 0.001 s  <<< ERROR!
java.lang.reflect.InaccessibleObjectException: Unable to make de.truncated.framework.shared.resources.ResourceManagerTest() accessible: module de.truncated.framework.shared does not "opens de.truncated.framework.shared.resources" to unnamed module @ed7f8b4

I'm googling since days now ... in jdk9 it can be simply adressed with --permit-illegal-access but this it not possible in jdk10 because this flag was removed.我几天以来一直在谷歌搜索......在 jdk9 中,它可以简单地使用--permit-illegal-access 解决,但这在 jdk10 中是不可能的,因为这个标志被删除了。 And the jdk10 code examples from junit5 and others on github don't use jigsaw how it seems.来自 junit5 和其他人在 github 上的 jdk10 代码示例似乎没有使用拼图。

So it looks like I miss something major in the maven, module or jvm args config.所以看起来我错过了 Maven、模块或 jvm args 配置中的一些主要内容。 It would be very nice if someone could provide help on this matter.如果有人可以就此事提供帮助,那就太好了。

Thank you very much!非常感谢你!

Some additional informations to the project which could be helpful:该项目的一些附加信息可能会有所帮助:

  • the primary code is configured by a module info file which exports (not opens) to everyone (its a framework like code base)主要代码由一个模块信息文件配置,该文件向所有人导出(不打开)(它是一个类似代码库的框架)
  • the test code is not modularized测试代码没有模块化
  • no jvm args are applied currently当前没有应用 jvm args

used versions:使用版本:

<properties>
   <java.version>10</java.version>
   <maven.compiler.version>3.7.0</maven.compiler.version>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <surefire.version>2.21.0</surefire.version>
   <asm.version>6.1.1</asm.version>
   <junit.jupiter.version>5.2.0</junit.jupiter.version>
   <junit.platform.version>1.2.0</junit.platform.version>
</properties>

depencies:依赖:

    <!--
    junit 5 dependency
    -->
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-launcher</artifactId>
        <version>${junit.platform.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>${junit.jupiter.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>${junit.jupiter.version}</version>
        <scope>test</scope>
    </dependency>

build plugins:构建插件:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.version}</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <verbose>true</verbose>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.ow2.asm</groupId>
                    <artifactId>asm</artifactId>
                    <version>${asm.version}</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${surefire.version}</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>${junit.platform.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.ow2.asm</groupId>
                    <artifactId>asm</artifactId>
                    <version>${asm.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

full stacktrace:完整的堆栈跟踪:

[INFO] Running de.truncated.framework.shared.resources.ResourceManagerTest
[ERROR] Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0 s <<< FAILURE! - in de.truncated.framework.shared.resources.ResourceManagerTest
[ERROR] singleThreadedResource  Time elapsed: 0 s  <<< ERROR!
java.lang.reflect.InaccessibleObjectException: Unable to make de.truncated.framework.shared.resources.ResourceManagerTest() accessible: module de.truncated.framework.shared does not "opens de.truncated.framework.shared.resources" to unnamed module @3af9c5b7
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
    at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:192)
    at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:185)
    at org.junit.platform.commons.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:1332)
    at org.junit.platform.commons.util.ReflectionUtils.newInstance(ReflectionUtils.java:429)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:60)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:208)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateAndPostProcessTestInstance(ClassTestDescriptor.java:195)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$0(ClassTestDescriptor.java:185)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$1(ClassTestDescriptor.java:189)
    at java.base/java.util.Optional.orElseGet(Optional.java:358)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$2(ClassTestDescriptor.java:188)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:81)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:58)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.prepare(HierarchicalTestExecutor.java:89)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:74)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
    at org.junit.platform.surefire.provider.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:132)
    at org.junit.platform.surefire.provider.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:111)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:379)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:340)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:413)

Today I've found two solutions for that issue.今天我找到了两个解决这个问题的方法。

1) You may add --add-opens to surefire plugin config: 1) 您可以将 --add-opens 添加到 surefire 插件配置中:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M1</version>
    <configuration>
        <argLine>--add-opens de.truncated.framework.shared/de.truncated.framework.shared.resources=ALL-UNNAMED</argLine>
    </configuration>
</plugin>

That will work because by default surefire plugin adds --add-reads to surefireargs file and JUnit5 uses reflection for which "reads" is not enough.这会起作用,因为默认情况下surefire插件将--add-reads添加到surefireargs文件中,而JUnit5使用反射,“读取”是不够的。

2) Alternatively you may mark all your JUnit5 test classes (and their annotated methods) as public . 2) 或者,您可以将所有 JUnit5 测试类(及其带注释的方法)标记为public That will also help because in that case JUnit will not use reflection when running tests (well, at least it doesn't in version 5.3.1).这也会有所帮助,因为在这种情况下,JUnit 在运行测试时不会使用反射(好吧,至少在 5.3.1 版中不会)。

PS I used maven-compiler-plugin version 3.8.0 and maven-surefire-plugin 3.0.0-M1. PS 我使用了 maven-compiler-plugin 版本 3.8.0 和 maven-surefire-plugin 3.0.0-M1。

There is a (new) option in the Maven Surefire plugin called useModulePath . Maven Surefire 插件中有一个(新)选项,称为useModulePath This option enables to use the traditional Java 8 class path instead of the module path and ignores a module-info.class not turning on the Java module mode, ie all class on the calls path can be used.此选项允许使用传统的 Java 8 类路径而不是模块路径,并忽略未打开 Java 模块模式的module-info.class ,即可以使用调用路径上的所有类。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M5</version>
    <configuration>
        <!--  allow to use unnamed modules -->
        <useModulePath>false</useModulePath>
    </configuration>
</plugin>

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

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