JDK-8232806 introduced the jdk.internal.lambda.disableEagerInitialization system property to be able to disable eager initialization of lambda classes. This was necessary to prevent side effects of class initializers triggered by such initialization in the context of the GraalVM native image tool.
However, the change as implemented means that the semantics of non-capturing lambdas in native images is different than in JVM execution. That is, the program below would print "true" on the JVM but "false" in a native image:
import java.util.function.Supplier;
public class LambdaIdentity {
public static void main(String[] args) {
System.out.println(lambda() == lambda());
}
private static Supplier<String> lambda() {
return () -> "value";
}
}
As [~briangoetz] correctly states in JDK-8232806, the above program is making assumptions above reference equality that the Java spec does not guarantee.
However, for better or worse there are programs out there that rely on this faulty assumption. Graal itself was one such program. This resulted in subtle and very hard to debug performance issues when using Graal in its libgraal form (i.e. as a native image). We do not wish the same experience on other users of native image and so propose that the implementation of reference equality for non-capturing lambdas should be the same independent of whether executing on the JVM or as a native image. At the very least, this should hold within the context of a single JDK version.