Reputation: 5399
I'm facing a error which starting to be really irritating.
Here is what I have:
1) Sonar 3.5 which uses JaCoCo as coverage tool.
2) Jmockit lib to perform testing with use of mocks.
3) Build process automized with maven.
So when I run first mvn clean install
which is ok and then I'm running mvn sonar:sonar
and what is happening here:
50Mb
(!), which is not acceptable. A lot of free space is just eaten up by such a logs on our CI machine. Here are the exceptions I've got:
java.lang.instrument.IllegalClassFormatException: Error while instrumenting class app/MyClass.
Caused by: java.lang.IllegalStateException: Class app/MyClass is already instrumented.
Assuming that suppression of such an exceptions is impossible I investigated it a little bit and found out that JaCoCo (a tool, which Sonar uses and a tool, which can't instrument already instrumented classes) have such a mode as offline instrumentation
(AFAIK Sonar neither support this offline instrumentation
or can suppress such a warnings). This thing is designed to be used exactly for such a cases. So I tried to set up JaCoCo as a plugin in maven, but I failed to do this cause JaCoCo can't find some execution file. When I'm running mvn clean install
the following error pops up:
[INFO] --- jacoco-maven-plugin:0.6.2.201302030002:report (report) @ webservice-mws --- [INFO] Skipping JaCoCo execution due to missing execution data file
If I'm not mistaken this execution file is the RESULT of the JaCoCo plugin. I'm totally frustrated and do not know what to do with this.
If somebody can help me with that it will be greatly appreciated!
Thanks in advance!
my pom.xml settings for JaCoCo plugin:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.2.201302030002</version>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Upvotes: 5
Views: 7777
Reputation: 1069
As per my insight into this research: It is possible to also use offline-instrumented classes with the JaCoCo Java agent. In this case, the configuration is taken from the agent options. The agent must be configured in a way that pre-instrumented classes are excluded, e.g. with " excludes=* ". Otherwise it will result in error messages on the console if the agent instruments such classes again likewise in your case. Jacoco plugin entry:-
<configuration>
<excludes>
<exclude>*</exclude>
</excludes>
</configuration>
The agent jacocoagent.jar is part of the JaCoCo distribution and includes all required dependencies. A Java agent can be activated with the following JVM option(in command line):
-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]
For JaCoCo agent options, consider the following link: http://www.jacoco.org/jacoco/trunk/doc/agent.html
As the agent jacocoagent.jar is part of the JaCoCo distribution, it gets automatically included in argLine parameter and need not be set explicitly, but we should to verify if jacocoagent.jar is shown as set in argLine while doing mvn clean install command
Upvotes: 3
Reputation: 148
I had the same problem. It appears to be fixed in jacoco plugin 0.7.1+. I am using 0.7.3.201502191951 and the problem went away for me.
Essentially the jMockit agent loads classes and retransforms them before the JaCoCo agent sees them. Afterwards JaCoCo can not perform the required instrumentations any more. see this link
https://github.com/jacoco/jacoco/issues/208
Upvotes: 1
Reputation: 1623
The problem is JMockit "reload" the class to mock them. Then JaCoCo try to instrument them again. It's at this moment the error occurs.
Note: It doesn't happen for mocked interfaces.
See the following stacktrace when running EclEmma+JaCoCo
java.lang.instrument.IllegalClassFormatException: Error while instrumenting class com/company/AbstractClass.
at org.jacoco.agent.rt.internal_9dd1198.CoverageTransformer.transform(CoverageTransformer.java:89)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170)
at mockit.internal.startup.Startup.redefineMethods(Startup.java:260)
at mockit.internal.RedefinitionEngine.redefineClasses(RedefinitionEngine.java:26)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineClass(BaseTypeRedefinition.java:172)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineClassAndItsSuperClasses(BaseTypeRedefinition.java:147)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineMethodsAndConstructorsInTargetType(BaseTypeRedefinition.java:134)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineTargetClassAndCreateInstanceFactory(BaseTypeRedefinition.java:197)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineType(BaseTypeRedefinition.java:57)
at mockit.internal.expectations.mocking.TypeRedefinition.redefineType(TypeRedefinition.java:47)
at mockit.internal.expectations.mocking.SharedFieldTypeRedefinitions.redefineTypeForMockField(SharedFieldTypeRedefinitions.java:60)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldType(FieldTypeRedefinitions.java:48)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldTypes(FieldTypeRedefinitions.java:38)
at mockit.internal.expectations.mocking.SharedFieldTypeRedefinitions.redefineTypesForTestClass(SharedFieldTypeRedefinitions.java:43)
at mockit.integration.internal.TestRunnerDecorator.handleMockFieldsForWholeTestClass(TestRunnerDecorator.java:135)
at mockit.integration.internal.TestRunnerDecorator.updateTestClassState(TestRunnerDecorator.java:34)
at mockit.integration.junit4.internal.JUnit4TestRunnerDecorator.handleMockingOutsideTestMethods(JUnit4TestRunnerDecorator.java:107)
at mockit.integration.junit4.internal.JUnit4TestRunnerDecorator.invokeExplosively(JUnit4TestRunnerDecorator.java:37)
at mockit.integration.junit4.internal.MockFrameworkMethod.invokeExplosively(MockFrameworkMethod.java:32)
at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at mockit.internal.util.MethodReflection.invokeWithCheckedThrows(MethodReflection.java:106)
at mockit.internal.mockups.MockMethodBridge.callMock(MockMethodBridge.java:85)
at mockit.internal.mockups.MockMethodBridge.invoke(MockMethodBridge.java:44)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.io.IOException: Error while instrumenting class com/afklm/cco/slt/integrator/batch/AbstractData.
at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrumentError(Instrumenter.java:147)
at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrument(Instrumenter.java:98)
at org.jacoco.agent.rt.internal_9dd1198.CoverageTransformer.transform(CoverageTransformer.java:87)
... 44 more
Caused by: java.lang.IllegalStateException: Class com/company/AbstractClass is already instrumented.
at org.jacoco.agent.rt.internal_9dd1198.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:81)
at org.jacoco.agent.rt.internal_9dd1198.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:79)
at org.jacoco.agent.rt.internal_9dd1198.asm.ClassVisitor.visitField(Unknown Source)
at org.jacoco.agent.rt.internal_9dd1198.asm.ClassReader.a(Unknown Source)
at org.jacoco.agent.rt.internal_9dd1198.asm.ClassReader.accept(Unknown Source)
at org.jacoco.agent.rt.internal_9dd1198.asm.ClassReader.accept(Unknown Source)
at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrument(Instrumenter.java:78)
at org.jacoco.agent.rt.internal_9dd1198.core.instr.Instrumenter.instrument(Instrumenter.java:96)
... 45 more
Upvotes: 0
Reputation: 1473
You may use Cobertura as your code coverage on Sonar 3.5.1.
To change it:
Worked like charm on my project ^_-
Upvotes: 4
Reputation: 10564
As far as I know message "Class app/MyClass is already instrumented." means that this class was already instrumented by JaCoCo. Here is some of possible reasons why this might happen:
For me your message looks a bit challenging to understand configuration, so I can't precisely say which of the cases above you're facing, but my bet on second one.
Hope this information will be useful for you. Feel free to come back to Sonar Users Mailing list, if this would not help you to solve issue.
Upvotes: 2