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.