TestNG tests execution against JDK 9 module causes InaccessibleObjectException

Sergey Korol :

I'm trying to transform the following library into Java 9 module: https://github.com/sskorol/test-data-supplier

Followed this guide: https://guides.gradle.org/building-java-9-modules

After some manipulations and refactoring (couldn't manage lombok issues, so just temporary removed it), I have the following 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;
}

And it even compiles / builds in case of tests' skipping. However, when I try to run a test task, I'm getting the following exception:

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 [email protected]/org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:31)
    at [email protected]/org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:410)
    at [email protected]/org.testng.internal.ClassHelper.createInstance(ClassHelper.java:323)
    at [email protected]/org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:126)
    at [email protected]/org.testng.internal.ClassImpl.getInstances(ClassImpl.java:191)
    at [email protected]/org.testng.TestClass.getInstances(TestClass.java:99)
    at [email protected]/org.testng.TestClass.initTestClassesAndInstances(TestClass.java:85)
    at [email protected]/org.testng.TestClass.init(TestClass.java:77)
    at [email protected]/org.testng.TestClass.<init>(TestClass.java:42)
    at [email protected]/org.testng.TestRunner.initMethods(TestRunner.java:423)
    at [email protected]/org.testng.TestRunner.init(TestRunner.java:250)
    at [email protected]/org.testng.TestRunner.init(TestRunner.java:220)
    at [email protected]/org.testng.TestRunner.<init>(TestRunner.java:161)
    at [email protected]/org.testng.SuiteRunner$DefaultTestRunnerFactory.newTestRunner(SuiteRunner.java:578)
    at [email protected]/org.testng.SuiteRunner.init(SuiteRunner.java:185)
    at [email protected]/org.testng.SuiteRunner.<init>(SuiteRunner.java:131)
    at [email protected]/org.testng.TestNG.createSuiteRunner(TestNG.java:1383)
    at [email protected]/org.testng.TestNG.createSuiteRunners(TestNG.java:1363)
    at [email protected]/org.testng.TestNG.runSuitesLocally(TestNG.java:1217)
    at [email protected]/org.testng.TestNG.runSuites(TestNG.java:1144)
    at [email protected]/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 [email protected]/org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:22)
    ... 48 more

It seems a bit confusing to me, as io.github.sskorol.testcases is a part of src/test/java and there's no module-info for tests. So I can't export this package to TestNG. Have an assumption that the root cause in a TestNG reflection usage within ObjectFactoryImpl against test classes.

Does anyone have any idea how to workaround it?

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

Nicolai :

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

It's one of two causes, yes. The other is that, apparently, Gradle runs your tests as a module. As you point out, there's no module descriptor for your tests. Gradle may use --patch-module to add the tests to the module containing the production code.

This question and answer provides a lot of background information and possible fixes. As a short term fix, I recommend to add opens io.github.sskorol.testcases to your production code's module descriptor. Judging by its name, I'd guess there is no such package yet, so you'd either have to rename or add a dummy class (I would prefer the former).

I would also take this issue to a Gradle mailing list or bug tracker. Unless we've overlooked something (entirely possible), Gradle's behavior is very unfortunate because it would require adapting the production code's module descriptor to the test code's needs.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=438013&siteId=1