For the following src/Example.java
class Example {
public static void main(String[] args) {
new java.sql.SQLException();
System.our.println("OK");
}
}
compiled by JDK 8
mkdir classes
javac src/Example.java -d classes
using JDK 8 execution of
rm jacoco.exec
java -javaagent:jacoco-0.8.14/lib/jacocoagent.jar -cp classes Example
java -jar jacoco-0.8.14/lib/jacococli.jar execinfo jacoco.exec | grep SQLException | wc -l
produces
whereas execution using JDK 9 and above up to JDK 26 produces
To instrument java.sql.SQLException prior to JDK 9 was required to use inclbootstrapclasses=true,
ie using JDK 8 execution of
rm jacoco.exec
java -javaagent:jacoco-0.8.14/lib/jacocoagent.jar=inclbootstrapclasses=true -cp classes Example
java -jar jacoco-0.8.14/lib/jacococli.jar execinfo jacoco.exec | grep SQLException | wc -l
produces
This difference comes from introduction of platform class loader by https://openjdk.org/jeps/261 in JDK 9.
By not instrumenting such classes by default
(eg by requiring for their instrumentation as it was before
inclbootstrapclasses to be true instead of default false)
we can get rid of exceptions when agent does not support bytecode version of classes in JDK EA
while supports bytecode version of classes whose coverage should be measured,
in which case such exceptions can already be safely ignored
(see #2151, #1742 (comment) and #1631 (comment)) - ie execution using JDK 27 EA produces
java.lang.instrument.IllegalClassFormatException: Error while instrumenting java/sql/SQLException with JaCoCo 0.8.14.202510111229/2eb2483.
at org.jacoco.agent.rt.internal_29a6edd.CoverageTransformer.transform(CoverageTransformer.java:94)
at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:257)
at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:594)
at java.base/java.lang.ClassLoader.defineClass2(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1080)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1064)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:177)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:735)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:678)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:604)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:639)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:608)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:578)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:502)
at Example.main(Example.java:3)
Caused by: java.io.IOException: Error while instrumenting java/sql/SQLException with JaCoCo 0.8.14.202510111229/2eb2483.
at org.jacoco.agent.rt.internal_29a6edd.core.instr.Instrumenter.instrumentError(Instrumenter.java:161)
at org.jacoco.agent.rt.internal_29a6edd.core.instr.Instrumenter.instrument(Instrumenter.java:111)
at org.jacoco.agent.rt.internal_29a6edd.CoverageTransformer.transform(CoverageTransformer.java:92)
... 15 more
Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 71
at org.jacoco.agent.rt.internal_29a6edd.asm.ClassReader.<init>(ClassReader.java:200)
at org.jacoco.agent.rt.internal_29a6edd.asm.ClassReader.<init>(ClassReader.java:180)
at org.jacoco.agent.rt.internal_29a6edd.asm.ClassReader.<init>(ClassReader.java:166)
at org.jacoco.agent.rt.internal_29a6edd.core.internal.instr.InstrSupport.classReaderFor(InstrSupport.java:280)
at org.jacoco.agent.rt.internal_29a6edd.core.instr.Instrumenter.instrument(Instrumenter.java:77)
at org.jacoco.agent.rt.internal_29a6edd.core.instr.Instrumenter.instrument(Instrumenter.java:109)
... 16 more
...
OK
0
while execution of
java -jar jacoco-0.8.14/lib/jacococli.jar report jacoco.exec \
--classfiles classes \
--sourcefiles src \
--html report
still produces correct code coverage report for Example.java
And similarly for JaCoCo 0.8.15 and JDK 28 EA.
Should also be noted that such classes can already be excluded from instrumentation using
or
'exclclassloader=jdk.internal.loader.ClassLoaders$PlatformClassLoader'
For the following
src/Example.javacompiled by JDK 8
using JDK 8 execution of
produces
whereas execution using JDK 9 and above up to JDK 26 produces
To instrument
java.sql.SQLExceptionprior to JDK 9 was required to useinclbootstrapclasses=true,ie using JDK 8 execution of
produces
This difference comes from introduction of platform class loader by https://openjdk.org/jeps/261 in JDK 9.
By not instrumenting such classes by default
(eg by requiring for their instrumentation as it was before
inclbootstrapclassesto betrueinstead of defaultfalse)we can get rid of exceptions when agent does not support bytecode version of classes in JDK EA
while supports bytecode version of classes whose coverage should be measured,
in which case such exceptions can already be safely ignored
(see #2151, #1742 (comment) and #1631 (comment)) - ie execution using JDK 27 EA produces
while execution of
still produces correct code coverage report for
Example.javaAnd similarly for JaCoCo 0.8.15 and JDK 28 EA.
Should also be noted that such classes can already be excluded from instrumentation using
or