Completed
Details
Assignee
UnassignedUnassignedReporter
Zach TellmanZach TellmanApproval
OkPatch
Code and TestPriority
CriticalAffects versions
Fix versions
Details
Details
Assignee
Unassigned
UnassignedReporter
Zach Tellman
Zach TellmanApproval
Ok
Patch
Code and Test
Priority
Affects versions
Fix versions
Created December 9, 2017 at 10:40 PM
Updated March 3, 2020 at 3:35 PM
Resolved June 27, 2018 at 3:10 PM
Calls to static interface methods compile on Java 8 but not on Java 9 because of a new bytecode restriction. As the usage of static interface methods increases, this problem will manifest more. I ran into it while using the AWS SDK (2.0 preview) which makes extensive usage of these methods.
public interface JDK8InterfaceMethods { // cannot call either of these from Clojure on Java 9 // throws IncompatibleClassChangeError per JVMS public static long staticMethod0(long v) { return v; } public static String staticMethod1(String s) { return s; } }
The original ticket had a repro here: https://github.com/ztellman/java9-failure
Cause: The JVM spec mandates that invocations to static interface methods refer to an InterfaceMethodref entry in the constant pool rather than simply to a Methodref. See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-5.html#jvms-5.4.3.3, describing the resolution rules for Methodrefs:
When resolving a method reference: If C is an interface, method resolution throws an IncompatibleClassChangeError.
Bytecode verification was tightened in Java 9 to check for this: https://bugs.openjdk.java.net/browse/JDK-8145148
ASM 5.1+ provide support for this.
Approach: First, upgrade to min Java 8 and latest ASM (6.2 right now) - this is now covered in ticket CLJ-2363. The patch here assumes CLJ-2363 has been completed as a baseline. The change here calls the newer ASM method to gen a static method call with awareness of static interface methods.
Patch: clj-2284-4.patch