Bug 577466 - [compiler] java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Enum; not a subtype of implementation type interface
Summary: [compiler] java.lang.invoke.LambdaConversionException: Invalid receiver type ...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.21   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 483219 551882 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-11-25 07:02 EST by Lukas Eder CLA
Modified: 2023-06-09 07:26 EDT (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lukas Eder CLA 2021-11-25 07:02:12 EST
The following code snippet implements an enum lookup by some enum property:

// -----------------------------------------------------------------------
package p;

import static java.util.function.Function.identity;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Lookup {

    private static final Map<Class<?>, Map<String, I>> LOOKUP = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    static <E extends Enum<E> & I> E lookupLiteral(Class<E> enumType, String literal) {
        return (E) LOOKUP.computeIfAbsent(enumType, t ->
            Stream.of(enumType.getEnumConstants()).collect(Collectors.<E, String, I>toMap(E::getLiteral, identity()))
        ).get(literal);
    }

    public static void main(String[] args) {
        System.out.println(Lookup.lookupLiteral(X.class, "a"));
    }

    interface I {
        String getLiteral();
    }

    enum X implements I {
        A("a");

        final String literal;

        X(String literal) {
            this.literal = literal;
        }

        @Override
        public String getLiteral() {
            return literal;
        }
    }
}
// -----------------------------------------------------------------------

It runs fine on JDK 17:

// -----------------------------------------------------------------------
$ java -version
openjdk version "17" 2021-09-14
OpenJDK Runtime Environment (build 17+35-2724)
OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)

$ java p/Lookup.java
A
// -----------------------------------------------------------------------

However, when I'm using Eclipse to compile this code, I'm getting the following error at runtime:

// -----------------------------------------------------------------------
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 x/p.Lookup.lambda$0(Lookup.java:17)
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
	at x/p.Lookup.lookupLiteral(Lookup.java:16)
	at x/p.Lookup.main(Lookup.java:22)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Enum; not a subtype of implementation type interface p.Lookup$I
	at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:271)
	at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:340)
	at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:134)
	... 7 more
// -----------------------------------------------------------------------

There used to be a similar bug in javac, which seems to have been fixed by now:
https://bugs.openjdk.java.net/browse/JDK-8141508
Comment 1 Lukas Eder CLA 2021-11-25 07:03:13 EST
The workaround is to remove the intersection type, which isn't strictly needed in this case (though it does add some type safety)

This works fine:

// -----------------------------------------------------------------------
    static <E extends I> E lookupLiteral(Class<E> enumType, String literal) {
        return (E) LOOKUP.computeIfAbsent(enumType, t ->
            Stream.of(enumType.getEnumConstants()).collect(Collectors.<E, String, I>toMap(E::getLiteral, identity()))
        ).get(literal);
    }
// -----------------------------------------------------------------------
Comment 2 Andrey Loskutov CLA 2022-04-07 07:55:04 EDT
Still there in I20220407-0240
Comment 3 Lauren Byrne CLA 2022-10-18 12:08:05 EDT
Version: 2022-03 (4.23.0)
Build id: 20220310-1457
Version: 2022-09 (4.25.0)
Build id: 20220908-1902

Still present in both of these.

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)  


Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Object; not a subtype of implementation type interface org.test.generic.name.TimePeriod
	at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:273)
	at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:340)
	at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:134)
Comment 4 Srikanth Sankaran CLA 2023-05-09 07:29:40 EDT
See who fixed https://bugs.openjdk.java.net/browse/JDK-8141508 :-)
Comment 6 Srikanth Sankaran CLA 2023-05-10 02:36:43 EDT
*** Bug 483219 has been marked as a duplicate of this bug. ***
Comment 7 Srikanth Sankaran CLA 2023-06-09 07:26:28 EDT
*** Bug 551882 has been marked as a duplicate of this bug. ***