Change in behaviour from Gradle 1.x to 2.x. We have a project with a simple class (in src/main/java/xxxx) that extends another 3rd party class. This class is assembled into a Jar and deployed to a container, which supplies other jars.
With Gradle 2.1, when running the test target for this project, the Gradle Test executor fails with a NoClassDefError exception. The reason is that the class being extended has dependencies on other classes which are not on the classpath (they are part of the container).
However this class is not used in any test. With Gradle 1.9 this class was not loaded, but with Gradle 2.1 it is, and causes the above exception.
Stack Trace:
org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not complete execution for process 'Gradle Test Executor 2'.
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: com/datasynapse/fabric/common/exception/ContainerException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2531)
at java.lang.Class.privateGetPublicMethods(Class.java:2651)
at java.lang.Class.getMethods(Class.java:1467)
at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:60)
at org.testng.TestRunner.initMethods(TestRunner.java:405)
at org.testng.TestRunner.init(TestRunner.java:231)
at org.testng.TestRunner.init(TestRunner.java:201)
at org.testng.TestRunner.<init>(TestRunner.java:150)
at org.testng.SuiteRunner$DefaultTestRunnerFactory.newTestRunner(SuiteRunner.java:523)
at org.testng.SuiteRunner.init(SuiteRunner.java:157)
at org.testng.SuiteRunner.<init>(SuiteRunner.java:111)
at org.testng.TestNG.createSuiteRunner(TestNG.java:1212)
at org.testng.TestNG.createSuiteRunners(TestNG.java:1199)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1053)
at org.testng.TestNG.run(TestNG.java:974)
at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:115)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:57)
... 21 more
Caused by: java.lang.ClassNotFoundException: com.datasynapse.fabric.common.exception.ContainerException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 39 more
Simplified class:
import com.datasynapse.fabric.container.ExecContainer;
public class Container extends ExecContainer {
}
The jar that includes ExecContainer is part of the classpath. However ExecContainer extends AbstractContainer that has static initialisers for classes that are not part of the classpath.
Container compiles fine and generates a class file. Classloading Container.class throws the NoClassDefFoundError as the classloader attempts to resolve all the dependencies. However in Gradle 1.9 it was never classloaded as it is not used in any test.
How can I prevent this from happening?