LMaker
LMaker

Reputation: 1620

Jacoco java.lang.instrument.IllegalClassFormatException: Error while instrumenting Class

I recently moved to another computer and needed to reset all my environment.

So, this tests was working before.

But I didnt remember which version of Java/JDK I was using before.

Well, the problem is:

java.lang.instrument.IllegalClassFormatException: Error while instrumenting path/to/class

I'm using Jacoco "0.8.1"

java --version
openjdk 17.0.1 2021-10-19

and JDK 1.8

Can anyone know how to handle with it?

Upvotes: 31

Views: 75658

Answers (4)

Mr-IDE
Mr-IDE

Reputation: 7651

This problem can happen when you have a multi-module Android project, and you're using Robolectric in your app unit tests, and you try to get code coverage data with Jacoco, using:

  • Android Studio ➔ View ➔ Tool Windows ➔ Project pane (of project files) ➔ Select the "test" folder ➔ Right-click it ➔ Run Tests in 'com.company.app' with Coverage

Android Studio will setup the unit tests (with code coverage) to run like this:

:app:testDebugUnitTest --tests "com.company.app.*"

So you may experience errors when the tests run. All of the non-Robolectric tests will run and pass, but the tests that are annotated with either @RunWith(RobolectricTestRunner::class) or @RunWith(AndroidJUnit4::class) will not run, and instead show errors like this:

java.lang.instrument.IllegalClassFormatException: Error while instrumenting path/to/class with JaCoCo 0.8.8.202204050719/5dcf34a.
    at org.jacoco.agent.rt.internal_b6258fc.CoverageTransformer.transform(CoverageTransformer.java:94)
    at java.instrument/java.lang.instrument.ClassFileTransformer.transform(Unknown Source)
    at java.instrument/sun.instrument.TransformerManager.transform(Unknown Source)
    at java.instrument/sun.instrument.InstrumentationImpl.transform(Unknown Source)
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(Unknown Source)
    at java.base/java.lang.ClassLoader.defineClass(Unknown Source)
    at org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:162)
    at org.robolectric.internal.bytecode.SandboxClassLoader.lambda$loadClass$0(SandboxClassLoader.java:136)
    at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:53)
    at org.robolectric.internal.bytecode.SandboxClassLoader.loadClass(SandboxClassLoader.java:136)
    at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
    at java.base/java.lang.Class.getDeclaredFields0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredFields(Unknown Source)
    at java.base/java.lang.Class.getDeclaredFields(Unknown Source)
    at org.junit.runners.model.TestClass.getSortedDeclaredFields(TestClass.java:77)
    at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:70)
    at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
    at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:111)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:91)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:74)
    at org.robolectric.internal.SandboxTestRunner$HelperTestRunner.<init>(SandboxTestRunner.java:353)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner.<init>(RobolectricTestRunner.java:569)

java.lang.IllegalStateException: Cannot process instrumented class com/company/app/MyClass. Please supply original non-instrumented classes.
    at org.jacoco.agent.rt.internal_b6258fc.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:238)

Bad return type
Exception Details:
  Location:
    android/content/res/ResourcesImpl.$$robo$$android_content_res_ResourcesImpl$loadComplexColorForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor; @828: areturn
  Reason:
    Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'android/content/res/ComplexColor' (from method signature)
  Current Frame:
    bci: @828
    flags: { }
    locals: { 'android/content/res/ResourcesImpl', 'android/content/res/Resources', 'android/util/TypedValue', integer, 'android/content/res/Resources$Theme', '[I', '[Z', 'java/lang/String', 'java/lang/Object', 'android/content/res/XmlResourceParser', 'android/util/AttributeSet', integer, 'java/lang/String' }
    stack: { 'java/lang/Object' }

In this case, you need to explicitly add the Java package of your app into the 'Run Configuration' of the unit tests, like this:

  • Android Studio ➔ Run ➔ Edit Configurations... ➔ Select the Gradle configuration for :app:testDebugUnitTest
  • At the right of the dialog, click on 'Modify options ▾' ➔ then click on 'Specify classes and packages' in the Code Coverage section.

Android Studio - Edit Run Configuration for Unit Tests - Modify Options

  • A blank space should now appear at the bottom of the dialog, with the title "Packages and classes to include in coverage data".
  • Click on the "+" symbol ➔ Add Package ➔ Select the main Java package of your app. It should display an entry like 'com.company.app.*'. Press OK.

Android Studio - Edit Run Configuration for Unit Tests - Add Packages and Classes

  • Then re-run all your unit tests. They should work now.

Upvotes: 1

Veena Vijay
Veena Vijay

Reputation: 51

While I was Testing my build in cmd using the command mvnw test, i got "Build Erorr" java.lang.instrument.IllegalClassFormatException: Error while instrumenting sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo.

Step to perform:

1.Where to analyse the error. Always check for build error or any test report under project folder /target/surefire-reports. As this a build erorr checkin the dump file Check for error message . In this particular scenario the error message is "Jacocojava.lang.instrument.IllegalClassFormatException: Error while instrumenting sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo"

2.Investigate what is causing this error. The java version i had is 17 and Jacoco version i had is 0.8.5. So check your java verison and Jacoco verison

3.Checking java version Cmd enter java - version : it will display the version example C:\Automation\projectJenkins\jgsu-spring-petclinic>java -version java version "17.0.6" 2023-01-17 LTS

4.For java 15 and above the jococ version compatable is 0.8.7. Open the pom file of your project and update jococ version. check under Generic properties . Update you version as 0.8.7

example:

<jacoco.version>0.8.7</jacoco.version>

save the file

  1. last step. test your build. cmd run MVNW test . The issue was reolved and succesfull build was built.

Upvotes: 5

kpgan8204
kpgan8204

Reputation: 301

Java 17 need jacoco 0.8.8 and above. reload pom.xml and it works

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.8</version>
</plugin>

Upvotes: 18

Godin
Godin

Reputation: 10564

Strange to see statement

and JDK 1.8

together with

java --version
openjdk 17.0.1 2021-10-19

from the last one seems that actually you're using JDK 17

I'm using Jacoco "0.8.1"

We (developers of JaCoCo) advice to always use latest released version as new versions come with fixes and improvements (IMO updating versions of your dependencies and tools - is a very good practice also in general), so please try this - as of today latest released JaCoCo version is 0.8.7, and exactly in this version JDK 17 support was added.

Upvotes: 30

Related Questions