Skip to content

Commit

Permalink
Add experimental support for Java 23 class files (#1553)
Browse files Browse the repository at this point in the history
  • Loading branch information
Godin committed Dec 12, 2023
1 parent 962b3fa commit 4bcc43f
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 19 deletions.
2 changes: 2 additions & 0 deletions .azure-pipelines/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:
JDK_VERSION: 21
JDK 22:
JDK_VERSION: 22
JDK 23:
JDK_VERSION: 23
pool:
vmImage: 'ubuntu-20.04'
steps:
Expand Down
14 changes: 14 additions & 0 deletions org.jacoco.build/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,20 @@
</properties>
</profile>

<profile>
<id>java23-bytecode</id>
<activation>
<property>
<name>bytecode.version</name>
<value>23</value>
</property>
</activation>
<properties>
<maven.compiler.source>13</maven.compiler.source>
<maven.compiler.target>13</maven.compiler.target>
</properties>
</profile>

<!-- This profile enables use of ECJ -->
<profile>
<id>ecj</id>
Expand Down
33 changes: 33 additions & 0 deletions org.jacoco.core.test.validation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,39 @@
</modules>
</profile>

<profile>
<id>java23-bytecode</id>
<activation>
<property>
<name>bytecode.version</name>
<value>23</value>
</property>
</activation>
<properties>
<!-- Kotlin 1.5.0 doesn't support compilation into 23 -->
<kotlin.compiler.jvmTarget>16</kotlin.compiler.jvmTarget>
<!-- Groovy 3.0.19 does not support compilation into 23 -->
<groovy.targetBytecode>16</groovy.targetBytecode>
<!-- see respective profile in org.jacoco.build about this override -->
<maven.compiler.source>23</maven.compiler.source>
<maven.compiler.target>23</maven.compiler.target>
</properties>
<modules>
<module>../org.jacoco.core.test.validation.kotlin</module>
<module>../org.jacoco.core.test.validation.java7</module>
<module>../org.jacoco.core.test.validation.java8</module>
<module>../org.jacoco.core.test.validation.java14</module>
<module>../org.jacoco.core.test.validation.java16</module>
<module>../org.jacoco.core.test.validation.java21</module>
<!-- Groovy 3.0.19 does not support Java 23
<module>../org.jacoco.core.test.validation.groovy</module>
-->
<!-- Scala 2.13.4 does not support Java 23 - see https://github.com/jacoco/jacoco/issues/1431
<module>../org.jacoco.core.test.validation.scala</module>
-->
</modules>
</profile>

</profiles>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public void should_ignore_synthetic_classes() throws Exception {
@Test
public void should_not_modify_class_bytes_to_support_next_version()
throws Exception {
final byte[] originalBytes = createClass(Opcodes.V21 + 1);
final byte[] originalBytes = createClass(Opcodes.V22 + 1);
final byte[] bytes = new byte[originalBytes.length];
System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length);
final long expectedClassId = CRC64.classId(bytes);
Expand All @@ -132,13 +132,13 @@ private static byte[] createClass(final int version) {
*/
@Test
public void analyzeClass_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V21 + 2);
final byte[] bytes = createClass(Opcodes.V22 + 2);
try {
analyzer.analyzeClass(bytes, "UnsupportedVersion");
fail("exception expected");
} catch (IOException e) {
assertExceptionMessage("UnsupportedVersion", e);
assertEquals("Unsupported class file major version 67",
assertEquals("Unsupported class file major version 68",
e.getCause().getMessage());
}
}
Expand Down Expand Up @@ -218,14 +218,14 @@ public void testAnalyzeClass_BrokenStream() throws IOException {
*/
@Test
public void analyzeAll_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V21 + 2);
final byte[] bytes = createClass(Opcodes.V22 + 2);
try {
analyzer.analyzeAll(new ByteArrayInputStream(bytes),
"UnsupportedVersion");
fail("exception expected");
} catch (IOException e) {
assertExceptionMessage("UnsupportedVersion", e);
assertEquals("Unsupported class file major version 67",
assertEquals("Unsupported class file major version 68",
e.getCause().getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public void setup() throws Exception {
@Test
public void should_not_modify_class_bytes_to_support_next_version()
throws Exception {
final byte[] originalBytes = createClass(Opcodes.V21 + 1);
final byte[] originalBytes = createClass(Opcodes.V22 + 1);
final byte[] bytes = new byte[originalBytes.length];
System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length);
final long expectedClassId = CRC64.classId(bytes);
Expand All @@ -123,13 +123,13 @@ private static byte[] createClass(final int version) {
*/
@Test
public void instrument_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V21 + 2);
final byte[] bytes = createClass(Opcodes.V22 + 2);
try {
instrumenter.instrument(bytes, "UnsupportedVersion");
fail("exception expected");
} catch (final IOException e) {
assertExceptionMessage("UnsupportedVersion", e);
assertEquals("Unsupported class file major version 67",
assertEquals("Unsupported class file major version 68",
e.getCause().getMessage());
}
}
Expand Down Expand Up @@ -221,14 +221,14 @@ public void testSerialization() throws Exception {
*/
@Test
public void instrumentAll_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V21 + 2);
final byte[] bytes = createClass(Opcodes.V22 + 2);
try {
instrumenter.instrumentAll(new ByteArrayInputStream(bytes),
new ByteArrayOutputStream(), "UnsupportedVersion");
fail("exception expected");
} catch (final IOException e) {
assertExceptionMessage("UnsupportedVersion", e);
assertEquals("Unsupported class file major version 67",
assertEquals("Unsupported class file major version 68",
e.getCause().getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public void setup() {
}

@Test
public void classReaderFor_should_read_java_22_class() {
final byte[] bytes = createJava22Class();
public void classReaderFor_should_read_java_23_class() {
final byte[] bytes = createJava23Class();

final ClassReader classReader = InstrSupport.classReaderFor(bytes);

Expand All @@ -53,16 +53,16 @@ public void classReaderFor_should_read_java_22_class() {
public void visit(final int version, final int access,
final String name, final String signature,
final String superName, final String[] interfaces) {
assertEquals(Opcodes.V21 + 1, version);
assertEquals(Opcodes.V22 + 1, version);
}
}, 0);

assertArrayEquals(createJava22Class(), bytes);
assertArrayEquals(createJava23Class(), bytes);
}

private static byte[] createJava22Class() {
private static byte[] createJava23Class() {
final ClassWriter cw = new ClassWriter(0);
cw.visit(Opcodes.V21 + 1, 0, "Foo", null, "java/lang/Object", null);
cw.visit(Opcodes.V22 + 1, 0, "Foo", null, "java/lang/Object", null);
cw.visitEnd();
return cw.toByteArray();
}
Expand Down Expand Up @@ -133,7 +133,8 @@ public void needFrames_should_return_true_for_versions_greater_than_or_equal_to_
assertTrue(InstrSupport.needsFrames(Opcodes.V19));
assertTrue(InstrSupport.needsFrames(Opcodes.V20));
assertTrue(InstrSupport.needsFrames(Opcodes.V21));
assertTrue(InstrSupport.needsFrames(Opcodes.V21 + 1));
assertTrue(InstrSupport.needsFrames(Opcodes.V22));
assertTrue(InstrSupport.needsFrames(Opcodes.V22 + 1));

assertTrue(InstrSupport.needsFrames(0x0100));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ public static void push(final MethodVisitor mv, final int value) {
*/
public static ClassReader classReaderFor(final byte[] b) {
final int originalVersion = getMajorVersion(b);
if (originalVersion == Opcodes.V21 + 1) {
if (originalVersion == Opcodes.V22 + 1) {
// temporarily downgrade version to bypass check in ASM
setMajorVersion(Opcodes.V21, b);
setMajorVersion(Opcodes.V22, b);
}
final ClassReader classReader = new ClassReader(b);
setMajorVersion(originalVersion, b);
Expand Down
6 changes: 6 additions & 0 deletions org.jacoco.doc/docroot/doc/changes.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ <h1>Change History</h1>

<h2>Snapshot Build @qualified.bundle.version@ (@build.date@)</h2>

<h3>New Features</h3>
<ul>
<li>Experimental support for Java 23 class files
(GitHub <a href="https://github.com/jacoco/jacoco/issues/1553">#1553</a>).</li>
</ul>

<h2>Release 0.8.11 (2023/10/14)</h2>

<h3>New Features</h3>
Expand Down

0 comments on commit 4bcc43f

Please sign in to comment.