I’m currently struggling with getting Jacoco plugin to run. My build is fine and all tests are working. Now I applied Jacoco plugin, set the jacoco.toolVersion to 0.7.1.201405082137 and tried to run one of my subprojects test task. Now every test fails with
{code}
java.lang.NoClassDefFoundError: org.junit.runner.Runner
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:61)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
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:601)
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 $Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
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:601)
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:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
{code}
I then removed the jacoco.toolVersion definition to use the version of Jacoco the plugin was developed against. Now the tests do not fail anymore, but it hangs forever trying to execute the first test.
Actually if I run with any but the latest version of Jacoco it hangs forever and when using the latest version as originally mentioned, there is the following on stderr:
{code}
java.lang.reflect.InvocationTargetException
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:601)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:382)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:407)
Caused by: java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170)
at mockit.internal.startup.Startup.redefineMethods(Startup.java:235)
at mockit.internal.startup.Startup.redefineMethods(Startup.java:227)
at mockit.internal.annotations.MockClassSetup.applyClassModifications(MockClassSetup.java:214)
at mockit.internal.annotations.MockClassSetup.redefineMethodsInClassHierarchy(MockClassSetup.java:177)
at mockit.internal.annotations.MockClassSetup.redefineMethods(MockClassSetup.java:164)
at mockit.internal.annotations.MockClassSetup.setUpStartupMock(MockClassSetup.java:158)
at mockit.internal.startup.JMockitInitialization.applyMockClass(JMockitInitialization.java:77)
at mockit.internal.startup.JMockitInitialization.setUpInternalStartupMock(JMockitInitialization.java:57)
at mockit.internal.startup.JMockitInitialization.loadInternalStartupMocksForJUnitIntegration(JMockitInitialization.java:39)
at mockit.internal.startup.JMockitInitialization.initialize(JMockitInitialization.java:26)
at mockit.internal.startup.Startup.initialize(Startup.java:74)
at mockit.internal.startup.Startup.initialize(Startup.java:63)
at mockit.internal.startup.Startup.agentmain(Startup.java:84)
... 6 more
java.lang.RuntimeException: com.sun.tools.attach.AgentInitializationException: Agent JAR loaded but agent failed to initialize
at mockit.internal.startup.JDK6AgentLoader.loadAgentAndDetachFromThisVM(JDK6AgentLoader.java:124)
at mockit.internal.startup.JDK6AgentLoader.loadAgent(JDK6AgentLoader.java:61)
at mockit.internal.startup.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:21)
at mockit.internal.startup.Startup.initializeIfNeeded(Startup.java:187)
at mockit.internal.startup.Startup.initializeIfPossible(Startup.java:220)
at org.junit.runner.Runner.<clinit>(Runner.java:22)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
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:601)
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 $Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
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:601)
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:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: com.sun.tools.attach.AgentInitializationException: Agent JAR loaded but agent failed to initialize
at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:121)
at mockit.internal.startup.JDK6AgentLoader.loadAgentAndDetachFromThisVM(JDK6AgentLoader.java:117)
... 35 more
The problem were incompatibilities between JaCoCo and JMockit. You need at least JaCoCo 0.7.1.201405082137 and JMockit 1.8 for the two to play nicely together. Otherwise you will have all sorts of trouble from infinite hangs up to strange exceptions about unsupported class modifications.
I doubt you can do much but to set up some deadlock recognition that kills the VM or similar. As far as I remember it was a deadlock inside JaCoCo and / or JMockit. I think you should be able to reproduce the issue if you apply the JaCoCo plugin with default toolVersion, add JMockit in version 1.4 (‘com.googlecode.jmockit:jmockit:1.4’) to testCompile and add a test that uses JMockit. Then the deadlock should occur and if you upgrade JaCoCo to toolVersion 0.7.1.201405082137, then the NoClassDefFoundError for org.junit.runner.Runner should occur. With JaCoCo at least toolVersion 0.7.1.201405082137 and JMockit at least version 1.8 no problems should occur as in those versions the incompatibilites were fixed.
Well, you could increase the default toolVersion of the JaCoCo plugin to 0.7.1.201405082137 and make sure that if JaCoCo plugin and JMockit plugin are both applied that JaCoCo is at least of version 0.7.1.201405082137 and JMockit is at least of version 1.8, because if either of the two tools is of older version, one of the various errors may / will appear.