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

Annotations with lambda expressions has parameter result in wrong behavior.

    Details

    • Subcomponent:
    • Resolved In Build:
      b123
    • CPU:
      generic
    • OS:
      generic
    • Verification:
      Verified

      Backports

        Description

        FULL PRODUCT VERSION :
        Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Linux 3.2.0-97-generic #137-Ubuntu SMP Thu Dec 17 18:11:47 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux


        A DESCRIPTION OF THE PROBLEM :
        Having static fields in an annotation type initialized by a lambda expression results in the annotations not being available in runtime.
        This seems to happen in specific cases only. The following static fields work without problems:
        Consumer<Integer> f2 = new B(); //with B a class implementing Consumer<Integer>
        Consumer<Integer> f3 = C::eat; //with C::eat begin a static method
        int f4 = 5;
        Supplier<Integer> f5 = ()->5;
        Consumer<Integer> f6 = new Consumer<Integer>() {
            public void accept(Integer t) {}
        };

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Compile the unit test, execute.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The test succeeds. The annotation can be retrieved using reflection.
        ACTUAL -
         The test fails. the annotation is not available.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.util.function.Consumer;

        import junit.framework.TestCase;

        @i
        public class AnnotationWithStaticLambda extends TestCase {
        public void testAnnotationWithStaticLambda() throws Exception {
        assertEquals(1, myAnnotMinimal2.class.getAnnotations().length);
        }

        }
        @Retention(RetentionPolicy.RUNTIME)
        @interface i {
        Consumer<Integer> f1 = a -> {return;}; // -> 0
        }

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

        CUSTOMER SUBMITTED WORKAROUND :
        Using an instance of a class instead of a lambda works.

          Issue Links

            Activity

            Hide
            psonal Pallavi Sonal added a comment -
            Attached test case executed on the following:
            JDK 8u66 - Fail
            JDK 8u72 - Fail
            JDK 9ea b93 - Fail
            Show
            psonal Pallavi Sonal added a comment - Attached test case executed on the following: JDK 8u66 - Fail JDK 8u72 - Fail JDK 9ea b93 - Fail
            Hide
            srastogi Shilpi Rastogi added a comment -
            Problem: Annotation with Lamda has parameters results into wrong behavior ( not considered as valid annotation) because
             According to JLS "By virtue of the AnnotationTypeElementDeclaration production, a method declaration in an annotation type declaration cannot have formal parameters, type parameters, or a throws clause. The following production from §4.3 is shown here for convenience:"
            (Ref: https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.1)


            Solution: According to JLS "An annotation type has no elements other than those defined by the methods it explicitly declares."
            (Ref https://docs.oracle.com/javase/specs/jls/se8/html/.html#jls-9jls-9.6.1)
            I believe that one of the meaning of above statement is "synthetic methods are not elements of Annotation Type.".
            So during Annotation parsing we should skip synthetic methods.
            Show
            srastogi Shilpi Rastogi added a comment - Problem: Annotation with Lamda has parameters results into wrong behavior ( not considered as valid annotation) because  According to JLS "By virtue of the AnnotationTypeElementDeclaration production, a method declaration in an annotation type declaration cannot have formal parameters, type parameters, or a throws clause. The following production from §4.3 is shown here for convenience:" (Ref: https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.1) Solution: According to JLS "An annotation type has no elements other than those defined by the methods it explicitly declares." (Ref https://docs.oracle.com/javase/specs/jls/se8/html/.html#jls-9jls-9.6.1) I believe that one of the meaning of above statement is "synthetic methods are not elements of Annotation Type.". So during Annotation parsing we should skip synthetic methods.
            Show
            srastogi Shilpi Rastogi added a comment - http://cr.openjdk.java.net/~srastogi/8147585/webrev.00/
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/3f4cce596ada
            User: mhaupt
            Date: 2016-06-09 07:35:47 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/3f4cce596ada User: mhaupt Date: 2016-06-09 07:35:47 +0000
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/3f4cce596ada
            User: lana
            Date: 2016-06-15 19:03:40 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/3f4cce596ada User: lana Date: 2016-06-15 19:03:40 +0000

              People

              • Assignee:
                srastogi Shilpi Rastogi
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: