Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8058112

Invalid BootstrapMethod for constructor/method reference

XMLWordPrintable

    • b17
    • x86_64
    • linux

        FULL PRODUCT VERSION :
        java version "1.8.0_20"
        Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
        Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Linux 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux


        EXTRA RELEVANT SYSTEM CONFIGURATION :
        Also reproducable on windows 7, not tested elsewhere

        A DESCRIPTION OF THE PROBLEM :
        When trying to apply a map() using a Function over a multi-bounded intersection generic type, the JRE fails with error message
        Caused by: java.lang.invoke.LambdaConversionException: Type mismatch for lambda argument 0: interface B is not convertible to interface A



        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run the main method in the code

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        No error message
        ACTUAL -
        java.lang.invoke.LambdaConversionException: Type mismatch for lambda argument 0: interface B is not convertible to interface A



        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        java.lang.invoke.LambdaConversionException: Type mismatch for lambda argument 0: interface B is not convertible to interface A


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.util.Arrays;
        import java.util.Comparator;
        import java.util.List;

        import static java.util.stream.Collectors.toList;

        public class Main {


            public static void main(String[] args) {
                Main main = new Main();
                main.toInfoListError(Arrays.asList(new Base()));
            }

            public <H extends B & A> List<Info> toInfoListError(List<H> list) {
                Comparator<B> byNameComparator = (B b1, B b2) -> b1.getB().compareToIgnoreCase(b2.getB());
                return list.stream().sorted(byNameComparator).map(Info::new).collect(toList());
            }

            public <H extends B & A> List<Info> toInfoListWorks(List<H> list) {
                Comparator<B> byNameComparator = (B b1, B b2) -> b1.getB().compareToIgnoreCase(b2.getB());
                return list.stream().sorted(byNameComparator).map(s -> new Info(s)).collect(toList());
            }
        }

        interface B {
            public String getB();
        }

        interface A {
            public long getA();
        }

        class Info {

            private final long a;
            private final String b;

            <H extends A & B> Info(H h) {
                a = h.getA();
                b = h.getB();
            }
        }

        class Base implements A, B {

            @Override
            public long getA() {
                return 7L;
            }

            @Override
            public String getB() {
                return "hello";
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Option A:
        Swap interfaces: replace <H extends B & A> to <H extends A & B> in method toInfoListError
        Order of the interfaces in the definition does not seem to bother the lambda used in method toInfoListWorks() though

        Option B:
        Use a lambda instead of a Function, cfr method toInfoListWorks()


              rfield Robert Field (Inactive)
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

                Created:
                Updated:
                Resolved: