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

javac is not correctly filtering non-members methods to obtain the function descriptor

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 8u5
    • Fix Version/s: 9
    • Component/s: tools
    • Subcomponent:
    • Resolved In Build:
      b134
    • CPU:
      x86
    • OS:
      os_x
    • Verification:
      Verified

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_05"
      Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Mac OS X 10.9.3

      A DESCRIPTION OF THE PROBLEM :
      Consider this snippet of java 8 code:

      public class Generics {
        public static <V, E extends Exception> V f(CheckedCallable1<V, E> callable) throws E {
          return callable.call();
        }
        public static <V, E extends Exception> V g(CheckedCallable2<V, E> callable) throws E {
          return callable.call();
        }
        public static void main(String[] args) throws Exception {
          f(() -> 1);
          g(() -> 1);
        }
      }

      interface Callable<V> {
        V call() throws Exception;
      }

      interface CheckedCallable1<V, E extends Exception> {
        V call() throws E;
      }

      interface CheckedCallable2<V, E extends Exception> extends Callable<V> {
        @Override V call() throws E;
      }

      The lambda at the call to f compiles fine, whereas the lambda at the call to g does not compile, but rather gives this compile error:

      Error:(10, 7) java: call() in <anonymous Generics$> cannot implement call() in CheckedCallable2
        overridden method does not throw java.lang.Exception

      I believe this is a compiler bug, in particular since the identical code with Exception replaced with IOException compiles fine.

      Additional details are at http://stackoverflow.com/questions/24199148/lambdas-and-functional-interfaces-with-generic-throw-clauses

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile the following java code:

      public class Generics {
        public static <V, E extends Exception> V f(CheckedCallable1<V, E> callable) throws E {
          return callable.call();
        }
        public static <V, E extends Exception> V g(CheckedCallable2<V, E> callable) throws E {
          return callable.call();
        }
        public static void main(String[] args) throws Exception {
          f(() -> 1);
          g(() -> 1);
        }
      }

      interface Callable<V> {
        V call() throws Exception;
      }

      interface CheckedCallable1<V, E extends Exception> {
        V call() throws E;
      }

      interface CheckedCallable2<V, E extends Exception> extends Callable<V> {
        @Override V call() throws E;
      }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect this code to compile.
      ACTUAL -
      The call to g results in the following compile error:

      Error:(10, 7) java: call() in <anonymous Generics$> cannot implement call() in CheckedCallable2
        overridden method does not throw java.lang.Exception

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Error:(10, 7) java: call() in <anonymous Generics$> cannot implement call() in CheckedCallable2
        overridden method does not throw java.lang.Exception

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class Generics {
        public static <V, E extends Exception> V f(CheckedCallable1<V, E> callable) throws E {
          return callable.call();
        }
        public static <V, E extends Exception> V g(CheckedCallable2<V, E> callable) throws E {
          return callable.call();
        }
        public static void main(String[] args) throws Exception {
          f(() -> 1);
          g(() -> 1);
        }
      }

      interface Callable<V> {
        V call() throws Exception;
      }

      interface CheckedCallable1<V, E extends Exception> {
        V call() throws E;
      }

      interface CheckedCallable2<V, E extends Exception> extends Callable<V> {
        @Override V call() throws E;
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      1) Don't extend a functional interface without a generic throws clause in a functional interface with a generic throws clause.

      or

      2) Use a subclass of Exception on the functional interface without generic throws clause.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                vromero Vicente Arturo Romero Zaldivar
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: