JDK-8269020 : Correct Java code compiles, but fails at runtime with BootstrapMethodError
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 11,15,16,17,18
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2021-06-17
  • Updated: 2022-10-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Blocks :  
Relates :  
Description
A DESCRIPTION OF THE PROBLEM :
Intersection types and different order of supertypes in type parameters cause incorrect bootstrap method parameters generated.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and execute the provided code example.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Code compiles without errors and prints "null" (or a compilation error is reported).
ACTUAL -
Exception in thread "main" java.lang.BootstrapMethodError: bootstrap method initialization exception
	at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:194)
	at java.base/java.lang.invoke.CallSite.makeSite(CallSite.java:307)
	at java.base/java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:258)
	at java.base/java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:248)
	at j.Test.test(Test.java:23)
	at j.Test.main(Test.java:27)
Caused by: java.lang.invoke.LambdaConversionException: Type mismatch for instantiated parameter 0: interface j.Test$X is not a subtype of interface j.Test$Y
	at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.checkDescriptor(AbstractValidatingLambdaMetafactory.java:308)
	at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:294)
	at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:328)
	at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:127)
	... 5 more


---------- BEGIN SOURCE ----------
package j;

public class Test {
    interface X {}
    interface Y {}

    interface A extends X, Y {}
    interface B extends X, Y {}

    interface IFoo<T extends Y & X> {
        void foo(T x);
    }

    static <T> T sel(T a, T b) { return a; }

    static class G<T extends X & Y> {
        void check(IFoo<? extends T> foo) {
            foo.foo(null);
        }
    }

    static void test(G<A> ga, G<B> gb) {
        sel(ga, gb).check(v -> System.out.println(v));
    }

    public static void main(String[] args) {
        test(new G<>(), new G<>());
    }
}

---------- END SOURCE ----------

FREQUENCY : always



Comments
See also https://bugs.openjdk.org/browse/JDK-8058112
27-10-2022

This may eventually be permitted by JDK-8174983, but with the current LambdaMetafactory it's up to javac to generate lambda methods with compatible signatures.
30-06-2021

Move to javac for evaluation. This test involves X & Y intersection types. Is that legitimate? IFoo::foo uses Y as the parameter in the method descriptor and and G::check(IFoo<? extends T>) invokes IFoo::foo with the proper signatuture. { public abstract void foo(T); descriptor: (LTest$Y;)V flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT Signature: #8 // (TT;)V } But the impl method for the lambda to invoke takes X as the parameter: private static void lambda$test$0(Test$X); descriptor: (LTest$X;)V flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC Code: stack=2, locals=1, args_size=1 0: getstatic #28 // Field java/lang/System.out:Ljava/io/PrintStream; 3: aload_0 4: invokevirtual #34 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 7: return Since Test$X is not a subtype of Test$Y, the BootstrapMethod call fails. 0: #63 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; Method arguments: #70 (LTest$Y;)V #72 REF_invokeStatic Test.lambda$test$0:(LTest$X;)V #75 (LTest$X;)V
30-06-2021

FWIW, the test works if the T type is expressed in a consistent order (always X & Y); i.e.: 8c8 < interface IFoo<T extends Y & X> { --- > interface IFoo<T extends X & Y> {
23-06-2021

Needs to be examined to see if this is a javac, runtime support, or something else.
18-06-2021

This is a regression issue. Following is my observation: JDK 8-pool: pass : null is printed JDK 9: fail JDK 11: fail JDK 14: fail JDK 15: fail JDK 16: fail JDK 17: fail JDK 18 ea: fail
18-06-2021

The issue is reproducible. BootstrapMethodError is thrown when executing the source. Exception in thread "main" java.lang.BootstrapMethodError: bootstrap method initialization exception at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:188) at java.base/java.lang.invoke.CallSite.makeSite(CallSite.java:315) at java.base/java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:281) at java.base/java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:271) at Test.test(Test.java:21) at Test.main(Test.java:25) Caused by: java.lang.invoke.LambdaConversionException: Type mismatch for dynamic parameter 0: interface Test$X is not a subtype of interface Test$Y at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.checkDescriptor(AbstractValidatingLambdaMetafactory.java:325) at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:311) at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:340) at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:134) ... 5 more
18-06-2021