JDK-8147585 : Annotations with lambda expressions has parameter result in wrong behavior.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 8u66,9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2016-01-13
  • Updated: 2016-10-13
  • Resolved: 2016-06-09
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.
JDK 8 JDK 9
8u112Fixed 9 b123Fixed
Related Reports
Relates :  
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.


Comments
http://cr.openjdk.java.net/~srastogi/8147585/webrev.00/
30-05-2016

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.
30-05-2016

Attached test case executed on the following: JDK 8u66 - Fail JDK 8u72 - Fail JDK 9ea b93 - Fail
19-01-2016