Incorrect bytecode generated for static methods on interfaces

Description

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

Environment

JDK 9 or higher

Attachments

14
  • 25 Jun 2018, 05:45 PM
  • 11 Jun 2018, 03:21 AM
  • 11 Jun 2018, 03:21 AM
  • 11 Jun 2018, 03:21 AM
  • 11 Jun 2018, 03:21 AM
  • 11 Jun 2018, 03:21 AM
  • 17 Feb 2018, 09:57 PM
  • 17 Feb 2018, 09:57 PM
  • 17 Feb 2018, 09:57 PM
  • 17 Feb 2018, 09:57 PM
  • 17 Feb 2018, 09:57 PM
  • 24 Dec 2017, 06:31 PM

Activity

Show:

Alex Miller June 25, 2018 at 5:45 PM

Squashed remaining patches (others in CLJ-2363) and screened.

Alex Miller June 22, 2018 at 3:18 PM

Marking as incomplete pending dependent on pulling the jdk 8 stuff out into CLJ-2363.

Ghadi Shayban June 11, 2018 at 3:21 AM

v3*.patch updates to ASM 6.2 final

Ghadi Shayban March 19, 2018 at 5:23 PM

Workaround macro:

(defmacro interface-static-call [sym & argtypes] `(let [m# (.getMethod ~(symbol (namespace sym)) ~(name sym) (into-array Class ~argtypes))] (fn [& args#] (.invoke m# nil (to-array args#))))) (def client (interface-static-call S3Client/create))

Ghadi Shayban March 19, 2018 at 4:15 PM

The patch in v2-0001 is already based on the ASM-6.1 branch but not the final release. Can bump it with the script in the commit comment.

Completed

Details

Assignee

Reporter

Approval

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

Flag notifications