java - TestNG 测试针对 JDK 9 模块的执行导致 InaccessibleObjectException

标签 java gradle testng java-9

我正在尝试将以下库转换为 Java 9 模块:https://github.com/sskorol/test-data-supplier

遵循本指南:https://guides.gradle.org/building-java-9-modules

经过一些操作和重构(无法处理 lombok 问题,所以只是暂时删除它),我有以下 module-info.java:

module io.github.sskorol {
    exports io.github.sskorol.core;
    exports io.github.sskorol.model;

    requires testng;
    requires vavr;
    requires streamex;
    requires joor;
    requires aspectjrt;
}

它甚至可以在测试跳过的情况下进行编译/构建。 但是,当我尝试运行测试 任务时,出现以下异常:

org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not complete execution for Gradle Test Executor 2.
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:63)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy1.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:120)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: org.testng.TestNGException: 
Cannot instantiate class io.github.sskorol.testcases.DataSupplierTests
    at testng@6.11/org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:31)
    at testng@6.11/org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:410)
    at testng@6.11/org.testng.internal.ClassHelper.createInstance(ClassHelper.java:323)
    at testng@6.11/org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:126)
    at testng@6.11/org.testng.internal.ClassImpl.getInstances(ClassImpl.java:191)
    at testng@6.11/org.testng.TestClass.getInstances(TestClass.java:99)
    at testng@6.11/org.testng.TestClass.initTestClassesAndInstances(TestClass.java:85)
    at testng@6.11/org.testng.TestClass.init(TestClass.java:77)
    at testng@6.11/org.testng.TestClass.<init>(TestClass.java:42)
    at testng@6.11/org.testng.TestRunner.initMethods(TestRunner.java:423)
    at testng@6.11/org.testng.TestRunner.init(TestRunner.java:250)
    at testng@6.11/org.testng.TestRunner.init(TestRunner.java:220)
    at testng@6.11/org.testng.TestRunner.<init>(TestRunner.java:161)
    at testng@6.11/org.testng.SuiteRunner$DefaultTestRunnerFactory.newTestRunner(SuiteRunner.java:578)
    at testng@6.11/org.testng.SuiteRunner.init(SuiteRunner.java:185)
    at testng@6.11/org.testng.SuiteRunner.<init>(SuiteRunner.java:131)
    at testng@6.11/org.testng.TestNG.createSuiteRunner(TestNG.java:1383)
    at testng@6.11/org.testng.TestNG.createSuiteRunners(TestNG.java:1363)
    at testng@6.11/org.testng.TestNG.runSuitesLocally(TestNG.java:1217)
    at testng@6.11/org.testng.TestNG.runSuites(TestNG.java:1144)
    at testng@6.11/org.testng.TestNG.run(TestNG.java:1115)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:129)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:88)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    ... 25 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public io.github.sskorol.testcases.DataSupplierTests() accessible: module io.github.sskorol does not "exports io.github.sskorol.testcases" to module testng
    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 testng@6.11/org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:22)
    ... 48 more

我觉得有点困惑,因为 io.github.sskorol.testcasessrc/test/java 的一部分,而且没有 module-用于测试的信息。所以我无法将这个包导出到 TestNG。假设根本原因是 ObjectFactoryImpl 中针对测试类的 TestNG 反射使用。

有没有人知道如何解决它?

环境:JDK 9(build 9+181),Gradle 4.1,TestNG 6.11

最佳答案

Have an assumption that the root cause in a TestNG reflection usage within ObjectFactoryImpl against test classes.

是的,这是两个原因之一。另一个是,显然,Gradle 将您的测试作为一个模块运行。正如您所指出的,您的测试没有模块描述符。 Gradle 可以使用 --patch-module将测试添加到包含生产代码的模块。

This question and answer提供了大量背景信息和可能的修复。作为短期修复,我建议将 opens io.github.sskorol.testcases 添加到生产代码的模块描述符中。从它的名字来看,我猜还没有这样的包,所以你必须重命名或添加一个虚拟类(我更喜欢前者)。

我还会将此问题提交给 Gradle 邮件列表或错误跟踪器。除非我们忽略了某些东西(完全有可能),否则 Gradle 的行为是非常不幸的,因为它需要调整生产代码的模块描述符以适应测试代码的需要。

关于java - TestNG 测试针对 JDK 9 模块的执行导致 InaccessibleObjectException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45673466/

相关文章:

kotlin - 在git bash中编译我的Kotlin测试

java - 在 Java 中通过 GUI 停止正在运行的进程

java - 内部 while 循环永远不会完成

java - Android复选框在一个 Activity 中选中,然后按钮出现在另一个 Activity 中

java - 使用 Kotlin Gradle DSL 向 Kotlin 项目添加集成测试

java - 运行 gradle 构建时出错

java - DBUnit 没有在每个方法之后清理和插入数据库,所以测试不是独立的

java - 如何将 Selenium Testng (java) 与 Testrail 测试用例集成

Java:从 Java 运行批处理脚本时检测用户提示

java - BufferedImage 未作为图像返回