Welcome! Please see the About page for a little more info on how this works.

+4 votes
in Records and Types by

Compiling a deftype that implements List on Java 21 will create a class that includes a reference to the (new to Java 21) SequencedCollection type (which introduces a new method reverse). Loading the compiled class will throw in an older Java runtime as the SequencedCollection type doesn't exist.

Given repro.clj:

(ns repro)

(deftype C []
  java.util.List)

Compiling with Java 21 JDK to a class, javap shows:

public final class repro.C implements java.util.List,clojure.lang.IType {
  public repro.C();
    Code:
       0: aload_0
       1: invokespecial #13  // Method java/lang/Object."<init>":()V
       4: return

  public static clojure.lang.IPersistentVector getBasis();
    Code:
       0: invokestatic  #20  // Method clojure/lang/Tuple.create:()Lclojure/lang/IPersistentVector;
       3: areturn

  public java.util.SequencedCollection reversed();
    Code:
       0: aload_0
       1: invokeinterface #25,  1   // InterfaceMethod java/util/List.reversed:()Ljava/util/List;
       6: areturn

  public static {};
    Code:
       0: return
}

Loading this class in Clojure with an older Java version throws:

user=> (require 'repro)
Execution error (ClassNotFoundException) at jdk.internal.loader.BuiltinClassLoader/loadClass (BuiltinClassLoader.java:641).
java.util.SequencedCollection

List includes a default reversed() method implementation for the SequenceCollection parent interface. Not sure why this forwarding method is getting created here but it's presumably different than others because it's a parent default method impl that we're forwarding to.

1 Answer

+1 vote
by

Logged as https://clojure.atlassian.net/browse/CLJ-2838 and I put a bit more analysis on the bottom of that.

ago by
Is there any sense of when this might be fixed? I had to pin my build workflow at an older Java release until it is.
ago by
We have done some work on the bridge method issue for next Clojure release but it's still a work in progress. I'm not sure whether that will actually avoid the issue or not though.

We are also moving to a new JVM baseline for compiled code in the next release, but that will likely be 17 not 21, so probably will also not be a "fix". For now, I would recommend to continue building with target of Java 8.
...