RFR[9]: 8147585: Annotations with lambda expressions has parameters result in wrong behavior.
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
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.rastogi@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
Thanks Paul for comments. Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.01/ Now processing only public abstract methods of interface. 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.rastogi@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
On 31 May 2016, at 10:35, shilpi.rastogi@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. 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.rastogi@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
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.rastogi@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#getDeclaredMe... "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.rastogi@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
On 31 May 2016, at 14:17, shilpi.rastogi@oracle.com wrote:
Hi All,
Please see updated webrev http://cr.openjdk.java.net/~srastogi/8147585/webrev.02/
I meant do something like this: static class MethodsWithAnnotations { @LambdaWithParameter public void testAnnotationLambdaWithParameter() { } @LambdaWithoutParameter public void testAnnotationLambdaWithoutParameter() { } } Then you don’t need to do: 49 if(!method.getName().equals("testAnnotationWithLambda")) {
On 5/31/2016 2:21 PM, Paul Sandoz wrote:
On 31 May 2016, at 10:35, shilpi.rastogi@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).
We may be getting our wires crossed. I was wondering if there were some existing tests that generate annotation classes by directly producing byte code that would otherwise not be possible with javac. If there are it might give us some clues. I was not suggesting as part of this fix you write some such tests.
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#getDeclaredMe... "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.
A synthetic method is one that must one of public, protected, default (package) access, and private (i don’t actually know if synthetic methods are stricter in their scope). But i think we are deviating off topic, which is the processing of declared methods by AnnotationType to build up the annotation property metadata. I just want to be sure that skipping all non-public non-abstract methods when processing is not gonna cause issues. It seems obvious it should skip such methods, but it has not been implemented that way. Perhaps this is just an oversight, i dunno, but sometimes things in a JDK are there for a reason, and it’s often hard to know. We can try making an offering to the Java gods and looking out for the eagle that flies straight and narrow to the right, or alternatively ask someone more expert in this area :-) AFAICT from debugging a little in this area the additional information added by processing never gets exposed, so it’s just wasted space/time. Paul.
If yes, Could you please suggest how to add testcases to test synthetic method? Shall I use ASM?
Regards, Shilp
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/ Thanks, Shilpi On 5/31/2016 7:57 PM, Paul Sandoz wrote:
"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."
Hi, I think this was caught by the verifier before 8 since you couldn't have concrete or private methods in an interface. Now you can (though not in Java for private ones). My spider sense tells me there might be something lurking here (though it was a while since this was in my L1 cache). It is not likely, but I'm not 100% sure that it is impossible to make javac produce a bridge when compiling an annotation type for example, so why not remove synthetic methods as well? Spending some time with ASM to do a bunch of tests not compilable in java might be useful, there should also be some frameworks in langtools to produce invalid classfiles IIRC. cheers /Joel On Tue, 31 May 2016 at 17:49 shilpi.rastogi@oracle.com < shilpi.rastogi@oracle.com> wrote:
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/
Thanks, Shilpi
On 5/31/2016 7:57 PM, Paul Sandoz wrote:
"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."
On 6/2/16 12:02 AM, Joel Borggrén-Franck wrote:
Hi,
I think this was caught by the verifier before 8 since you couldn't have concrete or private methods in an interface. Now you can (though not in Java for private ones).
My spider sense tells me there might be something lurking here (though it was a while since this was in my L1 cache). It is not likely, but I'm not 100% sure that it is impossible to make javac produce a bridge when compiling an annotation type for example, so why not remove synthetic methods as well?
I'm not an expert in annotation processing, but it bothers me as well, since current behavior looks too Java-centric. There are valid (in JVMS sense) class files which are not produced by javac or from java source file. What is expected behavior in such case? It is unfortunate when non-Java languages have to obey to Java rules. It reminds me a problem with Class.getSimpleName() (see JDK-8057919 [1]) we fixed some time ago. Best regards, Vladimir Ivanov [1] https://bugs.openjdk.java.net/browse/JDK-8057919
Spending some time with ASM to do a bunch of tests not compilable in java might be useful, there should also be some frameworks in langtools to produce invalid classfiles IIRC.
cheers /Joel
On Tue, 31 May 2016 at 17:49 shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com> <shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com>> wrote:
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/
Thanks, Shilpi
On 5/31/2016 7:57 PM, Paul Sandoz wrote: > >"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."
Thanks Vladimir and Joel!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.04/ Added restriction for synthetic methods as well. On 6/2/2016 5:04 PM, Vladimir Ivanov wrote:
On 6/2/16 12:02 AM, Joel Borggrén-Franck wrote:
Hi,
I think this was caught by the verifier before 8 since you couldn't have concrete or private methods in an interface. Now you can (though not in Java for private ones).
My spider sense tells me there might be something lurking here (though it was a while since this was in my L1 cache). It is not likely, but I'm not 100% sure that it is impossible to make javac produce a bridge when compiling an annotation type for example, so why not remove synthetic methods as well?
I'm not an expert in annotation processing, but it bothers me as well, since current behavior looks too Java-centric. There are valid (in JVMS sense) class files which are not produced by javac or from java source file.
What is expected behavior in such case? It is unfortunate when non-Java languages have to obey to Java rules. It reminds me a problem with Class.getSimpleName() (see JDK-8057919 [1]) we fixed some time ago. Best regards, Vladimir Ivanov
[1] https://bugs.openjdk.java.net/browse/JDK-8057919
Spending some time with ASM to do a bunch of tests not compilable in java might be useful, there should also be some frameworks in langtools to produce invalid classfiles IIRC.
Raised https://bugs.openjdk.java.net/browse/JDK-8158510 to include new test cases. Regards, Shilpi
cheers /Joel
On Tue, 31 May 2016 at 17:49 shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com> <shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com>> wrote:
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/
Thanks, Shilpi
On 5/31/2016 7:57 PM, Paul Sandoz wrote: > >"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."
Gentle reminder!! On 6/3/2016 11:40 AM, shilpi.rastogi@oracle.com wrote:
Thanks Vladimir and Joel!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.04/ Added restriction for synthetic methods as well.
On 6/2/2016 5:04 PM, Vladimir Ivanov wrote:
On 6/2/16 12:02 AM, Joel Borggrén-Franck wrote:
Hi,
I think this was caught by the verifier before 8 since you couldn't have concrete or private methods in an interface. Now you can (though not in Java for private ones).
My spider sense tells me there might be something lurking here (though it was a while since this was in my L1 cache). It is not likely, but I'm not 100% sure that it is impossible to make javac produce a bridge when compiling an annotation type for example, so why not remove synthetic methods as well?
I'm not an expert in annotation processing, but it bothers me as well, since current behavior looks too Java-centric. There are valid (in JVMS sense) class files which are not produced by javac or from java source file.
What is expected behavior in such case? It is unfortunate when non-Java languages have to obey to Java rules. It reminds me a problem with Class.getSimpleName() (see JDK-8057919 [1]) we fixed some time ago. Best regards, Vladimir Ivanov
[1] https://bugs.openjdk.java.net/browse/JDK-8057919
Spending some time with ASM to do a bunch of tests not compilable in java might be useful, there should also be some frameworks in langtools to produce invalid classfiles IIRC.
Raised https://bugs.openjdk.java.net/browse/JDK-8158510 to include new test cases.
Regards, Shilpi
cheers /Joel
On Tue, 31 May 2016 at 17:49 shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com> <shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com>> wrote:
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/
Thanks, Shilpi
On 5/31/2016 7:57 PM, Paul Sandoz wrote: > >"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."
Hello, The test 45 void testAnnotationWithLambda() { 46 Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods(); 47 for (Method method : methods) { 48 assertEquals(1, method.getDeclaredAnnotations().length); 49 } 50 } is very non-specific in what it is testing. A better test would include something like method.isAnnotationPresent(@LambdaWithParameter) && method.isAnnotationPresent(@LambdaWithouParameter) if both annotations were put on the same method. Cheers, -Joe On 6/6/2016 12:20 AM, shilpi.rastogi@oracle.com wrote:
Gentle reminder!!
On 6/3/2016 11:40 AM, shilpi.rastogi@oracle.com wrote:
Thanks Vladimir and Joel!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.04/ Added restriction for synthetic methods as well.
On 6/2/2016 5:04 PM, Vladimir Ivanov wrote:
On 6/2/16 12:02 AM, Joel Borggrén-Franck wrote:
Hi,
I think this was caught by the verifier before 8 since you couldn't have concrete or private methods in an interface. Now you can (though not in Java for private ones).
My spider sense tells me there might be something lurking here (though it was a while since this was in my L1 cache). It is not likely, but I'm not 100% sure that it is impossible to make javac produce a bridge when compiling an annotation type for example, so why not remove synthetic methods as well?
I'm not an expert in annotation processing, but it bothers me as well, since current behavior looks too Java-centric. There are valid (in JVMS sense) class files which are not produced by javac or from java source file.
What is expected behavior in such case? It is unfortunate when non-Java languages have to obey to Java rules. It reminds me a problem with Class.getSimpleName() (see JDK-8057919 [1]) we fixed some time ago. Best regards, Vladimir Ivanov
[1] https://bugs.openjdk.java.net/browse/JDK-8057919
Spending some time with ASM to do a bunch of tests not compilable in java might be useful, there should also be some frameworks in langtools to produce invalid classfiles IIRC.
Raised https://bugs.openjdk.java.net/browse/JDK-8158510 to include new test cases.
Regards, Shilpi
cheers /Joel
On Tue, 31 May 2016 at 17:49 shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com> <shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com>> wrote:
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/
Thanks, Shilpi
On 5/31/2016 7:57 PM, Paul Sandoz wrote: > >"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."
Thanks Joseph!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.05/ Regards, Shilpi On 6/7/2016 6:00 AM, Joseph D. Darcy wrote:
Hello,
The test
45 void testAnnotationWithLambda() { 46 Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods(); 47 for (Method method : methods) { 48 assertEquals(1, method.getDeclaredAnnotations().length); 49 } 50 }
is very non-specific in what it is testing. A better test would include something like
method.isAnnotationPresent(@LambdaWithParameter) && method.isAnnotationPresent(@LambdaWithouParameter)
if both annotations were put on the same method.
Cheers,
-Joe
On 6/6/2016 12:20 AM, shilpi.rastogi@oracle.com wrote:
Gentle reminder!!
On 6/3/2016 11:40 AM, shilpi.rastogi@oracle.com wrote:
Thanks Vladimir and Joel!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.04/ Added restriction for synthetic methods as well.
On 6/2/2016 5:04 PM, Vladimir Ivanov wrote:
On 6/2/16 12:02 AM, Joel Borggrén-Franck wrote:
Hi,
I think this was caught by the verifier before 8 since you couldn't have concrete or private methods in an interface. Now you can (though not in Java for private ones).
My spider sense tells me there might be something lurking here (though it was a while since this was in my L1 cache). It is not likely, but I'm not 100% sure that it is impossible to make javac produce a bridge when compiling an annotation type for example, so why not remove synthetic methods as well?
I'm not an expert in annotation processing, but it bothers me as well, since current behavior looks too Java-centric. There are valid (in JVMS sense) class files which are not produced by javac or from java source file.
What is expected behavior in such case? It is unfortunate when non-Java languages have to obey to Java rules. It reminds me a problem with Class.getSimpleName() (see JDK-8057919 [1]) we fixed some time ago. Best regards, Vladimir Ivanov
[1] https://bugs.openjdk.java.net/browse/JDK-8057919
Spending some time with ASM to do a bunch of tests not compilable in java might be useful, there should also be some frameworks in langtools to produce invalid classfiles IIRC.
Raised https://bugs.openjdk.java.net/browse/JDK-8158510 to include new test cases.
Regards, Shilpi
cheers /Joel
On Tue, 31 May 2016 at 17:49 shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com> <shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com>> wrote:
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/
Thanks, Shilpi
On 5/31/2016 7:57 PM, Paul Sandoz wrote: > >"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."
Hi Shilpi, I will be happy to sponsor the push. Best, Michael
Am 07.06.2016 um 11:39 schrieb shilpi.rastogi@oracle.com:
Thanks Joseph!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.05/
Regards, Shilpi
On 6/7/2016 6:00 AM, Joseph D. Darcy wrote:
Hello,
The test
45 void testAnnotationWithLambda() { 46 Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods(); 47 for (Method method : methods) { 48 assertEquals(1, method.getDeclaredAnnotations().length); 49 } 50 }
is very non-specific in what it is testing. A better test would include something like
method.isAnnotationPresent(@LambdaWithParameter) && method.isAnnotationPresent(@LambdaWithouParameter)
if both annotations were put on the same method.
Cheers,
-Joe
On 6/6/2016 12:20 AM, shilpi.rastogi@oracle.com wrote:
Gentle reminder!!
On 6/3/2016 11:40 AM, shilpi.rastogi@oracle.com wrote:
Thanks Vladimir and Joel!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.04/ Added restriction for synthetic methods as well.
On 6/2/2016 5:04 PM, Vladimir Ivanov wrote:
On 6/2/16 12:02 AM, Joel Borggrén-Franck wrote:
Hi,
I think this was caught by the verifier before 8 since you couldn't have concrete or private methods in an interface. Now you can (though not in Java for private ones).
My spider sense tells me there might be something lurking here (though it was a while since this was in my L1 cache). It is not likely, but I'm not 100% sure that it is impossible to make javac produce a bridge when compiling an annotation type for example, so why not remove synthetic methods as well?
I'm not an expert in annotation processing, but it bothers me as well, since current behavior looks too Java-centric. There are valid (in JVMS sense) class files which are not produced by javac or from java source file.
What is expected behavior in such case? It is unfortunate when non-Java languages have to obey to Java rules. It reminds me a problem with Class.getSimpleName() (see JDK-8057919 [1]) we fixed some time ago. Best regards, Vladimir Ivanov
[1] https://bugs.openjdk.java.net/browse/JDK-8057919
Spending some time with ASM to do a bunch of tests not compilable in java might be useful, there should also be some frameworks in langtools to produce invalid classfiles IIRC.
Raised https://bugs.openjdk.java.net/browse/JDK-8158510 to include new test cases.
Regards, Shilpi
cheers /Joel
On Tue, 31 May 2016 at 17:49 shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com> <shilpi.rastogi@oracle.com <mailto:shilpi.rastogi@oracle.com>> wrote:
Thanks Paul!! Please see http://cr.openjdk.java.net/~srastogi/8147585/webrev.03/
Thanks, Shilpi
On 5/31/2016 7:57 PM, Paul Sandoz wrote: > >"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."
-- <http://www.oracle.com/> Dr. Michael Haupt | Principal Member of Technical Staff Phone: +49 331 200 7277 | Fax: +49 331 200 7561 Oracle Java Platform Group | LangTools Team | Nashorn Oracle Deutschland B.V. & Co. KG | Schiffbauergasse 14 | 14467 Potsdam, Germany ORACLE Deutschland B.V. & Co. KG | Hauptverwaltung: Riesstraße 25, D-80992 München Registergericht: Amtsgericht München, HRA 95603 Komplementärin: ORACLE Deutschland Verwaltung B.V. | Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister der Handelskammer Midden-Nederland, Nr. 30143697 Geschäftsführer: Alexander van der Ven, Jan Schultheiss, Val Maher <http://www.oracle.com/commitment> Oracle is committed to developing practices and products that help protect the environment
participants (6)
-
Joel Borggrén-Franck
-
Joseph D. Darcy
-
Michael Haupt
-
Paul Sandoz
-
shilpi.rastogi@oracle.com
-
Vladimir Ivanov