Skip to content

Commit

Permalink
Add experimental support for Java 16
Browse files Browse the repository at this point in the history
  • Loading branch information
marchof committed Jun 16, 2020
1 parent d60a5b2 commit 838f9ec
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 20 deletions.
7 changes: 7 additions & 0 deletions .travis.sh
Expand Up @@ -75,6 +75,9 @@ case "$JDK" in
15-ea)
install_jdk $JDK15_EA_URL
;;
16-ea)
install_jdk $JDK16_EA_URL
;;
esac

# Do not use "~/.mavenrc" set by Travis (https://github.com/travis-ci/travis-ci/issues/3893),
Expand Down Expand Up @@ -110,6 +113,10 @@ case "$JDK" in
mvn -V -B -e verify -Dbytecode.version=15 \
--settings=./.travis/settings.xml
;;
16-ea)
mvn -V -B -e verify -Dbytecode.version=16 \
--settings=./.travis/settings.xml
;;
*)
echo "Incorrect JDK [$JDK]"
exit 1;
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -31,5 +31,6 @@ env:
- JDK=13
- JDK=14
- JDK=15-ea
- JDK=16-ea

script: ./.travis.sh
14 changes: 14 additions & 0 deletions org.jacoco.build/pom.xml
Expand Up @@ -841,6 +841,20 @@
</properties>
</profile>

<profile>
<id>java16-bytecode</id>
<activation>
<property>
<name>bytecode.version</name>
<value>16</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
25 changes: 25 additions & 0 deletions org.jacoco.core.test.validation/pom.xml
Expand Up @@ -246,6 +246,31 @@
<module>../org.jacoco.core.test.validation.scala</module>
</modules>
</profile>

<profile>
<id>java16-bytecode</id>
<activation>
<property>
<name>bytecode.version</name>
<value>16</value>
</property>
</activation>
<properties>
<!-- see respective profile in org.jacoco.build about this override -->
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</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>
<!-- Groovy 2.5.8 doesn't support bytecode version 16
<module>../org.jacoco.core.test.validation.groovy</module>
-->
<module>../org.jacoco.core.test.validation.scala</module>
</modules>
</profile>
</profiles>

</project>
Expand Up @@ -107,7 +107,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.V14 + 1);
final byte[] originalBytes = createClass(Opcodes.V15 + 1);
final byte[] bytes = new byte[originalBytes.length];
System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length);
final long expectedClassId = CRC64.classId(bytes);
Expand All @@ -130,14 +130,14 @@ private static byte[] createClass(final int version) {
*/
@Test
public void analyzeClass_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V14 + 2);
final byte[] bytes = createClass(Opcodes.V15 + 2);
try {
analyzer.analyzeClass(bytes, "UnsupportedVersion");
fail("exception expected");
} catch (IOException e) {
assertEquals("Error while analyzing UnsupportedVersion.",
e.getMessage());
assertEquals("Unsupported class file major version 60",
assertEquals("Unsupported class file major version 61",
e.getCause().getMessage());
}
}
Expand Down Expand Up @@ -217,15 +217,15 @@ public void testAnalyzeClass_BrokenStream() throws IOException {
*/
@Test
public void analyzeAll_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V14 + 2);
final byte[] bytes = createClass(Opcodes.V15 + 2);
try {
analyzer.analyzeAll(new ByteArrayInputStream(bytes),
"UnsupportedVersion");
fail("exception expected");
} catch (IOException e) {
assertEquals("Error while analyzing UnsupportedVersion.",
e.getMessage());
assertEquals("Unsupported class file major version 60",
assertEquals("Unsupported class file major version 61",
e.getCause().getMessage());
}
}
Expand Down
Expand Up @@ -29,6 +29,7 @@
import static org.objectweb.asm.Opcodes.V12;
import static org.objectweb.asm.Opcodes.V13;
import static org.objectweb.asm.Opcodes.V14;
import static org.objectweb.asm.Opcodes.V15;
import static org.objectweb.asm.Opcodes.V1_1;
import static org.objectweb.asm.Opcodes.V1_2;
import static org.objectweb.asm.Opcodes.V1_3;
Expand Down Expand Up @@ -129,7 +130,12 @@ public void test_14() throws IOException {

@Test
public void test_15() throws IOException {
testVersion(V14 + 1, true);
testVersion(V15, true);
}

@Test
public void test_16() throws IOException {
testVersion(V15 + 1, true);
}

private void testVersion(int version, boolean frames) throws IOException {
Expand Down
Expand Up @@ -99,7 +99,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.V14 + 1);
final byte[] originalBytes = createClass(Opcodes.V15 + 1);
final byte[] bytes = new byte[originalBytes.length];
System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length);
final long expectedClassId = CRC64.classId(bytes);
Expand All @@ -122,14 +122,14 @@ private static byte[] createClass(final int version) {
*/
@Test
public void instrument_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V14 + 2);
final byte[] bytes = createClass(Opcodes.V15 + 2);
try {
instrumenter.instrument(bytes, "UnsupportedVersion");
fail("exception expected");
} catch (final IOException e) {
assertEquals("Error while instrumenting UnsupportedVersion.",
e.getMessage());
assertEquals("Unsupported class file major version 60",
assertEquals("Unsupported class file major version 61",
e.getCause().getMessage());
}
}
Expand Down Expand Up @@ -224,15 +224,15 @@ public void testSerialization() throws Exception {
*/
@Test
public void instrumentAll_should_throw_exception_for_unsupported_class_file_version() {
final byte[] bytes = createClass(Opcodes.V14 + 2);
final byte[] bytes = createClass(Opcodes.V15 + 2);
try {
instrumenter.instrumentAll(new ByteArrayInputStream(bytes),
new ByteArrayOutputStream(), "UnsupportedVersion");
fail("exception expected");
} catch (final IOException e) {
assertEquals("Error while instrumenting UnsupportedVersion.",
e.getMessage());
assertEquals("Unsupported class file major version 60",
assertEquals("Unsupported class file major version 61",
e.getCause().getMessage());
}
}
Expand Down
Expand Up @@ -43,8 +43,8 @@ public void setup() {
}

@Test
public void classReaderFor_should_read_java_15_class() {
final byte[] bytes = createJava15Class();
public void classReaderFor_should_read_java_16_class() {
final byte[] bytes = createJava16Class();

final ClassReader classReader = InstrSupport.classReaderFor(bytes);

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

assertArrayEquals(createJava15Class(), bytes);
assertArrayEquals(createJava16Class(), bytes);
}

private static byte[] createJava15Class() {
private static byte[] createJava16Class() {
final ClassWriter cw = new ClassWriter(0);
cw.visit(Opcodes.V14 + 1, 0, "Foo", null, "java/lang/Object", null);
cw.visit(Opcodes.V15 + 1, 0, "Foo", null, "java/lang/Object", null);
cw.visitEnd();
return cw.toByteArray();
}
Expand Down Expand Up @@ -126,7 +126,8 @@ public void needFrames_should_return_true_for_versions_greater_than_or_equal_to_
assertTrue(InstrSupport.needsFrames(Opcodes.V12));
assertTrue(InstrSupport.needsFrames(Opcodes.V13));
assertTrue(InstrSupport.needsFrames(Opcodes.V14));
assertTrue(InstrSupport.needsFrames(Opcodes.V14 + 1));
assertTrue(InstrSupport.needsFrames(Opcodes.V15));
assertTrue(InstrSupport.needsFrames(Opcodes.V15 + 1));

assertTrue(InstrSupport.needsFrames(0x0100));
}
Expand Down
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.V14 + 1) {
if (originalVersion == Opcodes.V15 + 1) {
// temporarily downgrade version to bypass check in ASM
setMajorVersion(Opcodes.V14, b);
setMajorVersion(Opcodes.V15, b);
}
final ClassReader classReader = new ClassReader(b);
setMajorVersion(originalVersion, b);
Expand Down
2 changes: 2 additions & 0 deletions org.jacoco.doc/docroot/doc/changes.html
Expand Up @@ -25,6 +25,8 @@ <h3>New Features</h3>
<li>JaCoCo now officially supports Java 14.</li>
<li>Experimental support for Java 15 class files
(GitHub <a href="https://github.com/jacoco/jacoco/issues/992">#992</a>).</li>
<li>Experimental support for Java 16 class files
(GitHub <a href="https://github.com/jacoco/jacoco/issues/1059">#1059</a>).</li>
<li>Methods <code>toString</code>, <code>hashCode</code> and <code>equals</code>
generated by compiler for records are filtered out during generation of report
(GitHub <a href="https://github.com/jacoco/jacoco/issues/990">#990</a>).</li>
Expand Down

0 comments on commit 838f9ec

Please sign in to comment.