Hi All,

Please see updated webrev http://cr.openjdk.java.net/~srastogi/8147585/webrev.02/

On 5/31/2016 2:21 PM, Paul Sandoz wrote:
On 31 May 2016, at 10:35, shilpi.rast...@oracle.com wrote:

Thanks Paul for comments.

Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.01/

Now processing only public abstract methods of interface.

Thanks. It would be good to get some got feedback from those wiser than I in 
this regard.

Have you looked at the existing annotation-based tests to see if they test edge 
cases e.g. annotation classes generated with incorrect methods? that might give 
us some clues.
I saw existing annotation-based test, valid modifier for annotations, valid method for annotation tests we are checking in javac code. default, static, private modifier we are restricting at compile time so we can not add test cases for this (compilation will fail).

So only scenario i can add is for synthetic methods. ( according to my assumption)
In AnnotationType.java

public Method[] run() {
     // Initialize memberTypes and defaultValues
     return annotationClass.getDeclaredMethods();
  }
});

As here, calling getDeclaredMethods() on annotationclass and getDeclaredMethods() doc says

https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredMethods--
"Returns an array containing Method objects reflecting all the declared methods of the class or interface represented by this Class object, including public, protected, default (package) access, and private methods, but excluding inherited methods."

Doc did not mention anything about synthetic methods so i am not sure this is expected behavior or not. If yes, Could you please suggest how to add testcases to test synthetic method?
Shall I use ASM?

Regards,
Shilpi


Testing wise:

- you can avoid the filtering of the test method by placing the annotations in 
another auxiliary class (my preference is to nest rather than using auxiliary 
classes, up to you)

- there is a couple of minor style inconsistencies e.g. a space here "@ interface 
LambdaWithoutParameter"

- 30  * @run testng/othervm -ea -esa AnnotationWithLambda

You can just do:

   @run testng AnnotationWithLambda

?

Thanks,
Paul.




Thanks,
Shilpi

On 5/30/2016 6:35 PM, Paul Sandoz wrote:
Hi Shilpi,

You have found the right place but i am not sure your fix is entirely correct.

(Tip: if you use  -Xlog:exceptions=info you can observe the IAE exception when 
the annotation is processed)

In your test you have:

@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@ interface LambdaWithParameter {
     Consumer<Integer> f1 = a -> {
         System.out.println("lambda has parameter");
     };
}

@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@ interface LambdaWithoutParameter {
     Runnable r = () -> System.out.println("lambda without parameter");
}


Both of those annotations will have static synthetic methods generated by the 
compiler that the indy resolves and links to (look at the javap output). The 
former will have a method with one parameter.


The code in sun/reflect/annotation/AnnotationType.java:

for (Method method : methods) {
     if (method.getParameterTypes().length != 0)
         throw new IllegalArgumentException(method + " has params");

has thrown the IAE since 2004, but it’s not clear why it was added as opposed 
to something more general (see below).


The correct fix appears to be to skip over any non-abstract/non-public methods. 
Thus only public abstract methods get processed.

Your current fix now processes synthetic methods with parameters, in addition 
to those which were already processed such as synthetic methods without 
parameters, or even private methods that could have been generated by some 
tool. I dunno how much say the verifier has in all this, perhaps little or no 
say.

Thus non-public/non-abstract methods could add inconsistent information to the 
data structures of AnnotationType. Perhaps this is mostly harmless?

Perhaps Joel (CC’ed) can she some more light on this?

Paul.


On 30 May 2016, at 08:00, shilpi.rast...@oracle.com wrote:

Hi All,

Please review fix for https://bugs.openjdk.java.net/browse/JDK-8147585
http://cr.openjdk.java.net/~srastogi/8147585/webrev.00/

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: We should skip synthetic methods during Annotation parsing. 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)


Thanks,
Shilpi

Reply via email to