8147585: Annotations with lambda expressions has parameter result in wrong behavior.
Reviewed-by: psandoz, darcy, jfranck, vlivanov, mhaupt
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Wed Jun 08 17:30:37 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Thu Jun 09 09:33:37 2016 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -118,16 +118,22 @@
members = new HashMap<>(methods.length+1, 1.0f);
for (Method method : methods) {
- if (method.getParameterTypes().length != 0)
- throw new IllegalArgumentException(method + " has params");
- String name = method.getName();
- Class<?> type = method.getReturnType();
- memberTypes.put(name, invocationHandlerReturnType(type));
- members.put(name, method);
+ if (Modifier.isPublic(method.getModifiers()) &&
+ Modifier.isAbstract(method.getModifiers()) &&
+ !method.isSynthetic()) {
+ if (method.getParameterTypes().length != 0) {
+ throw new IllegalArgumentException(method + " has params");
+ }
+ String name = method.getName();
+ Class<?> type = method.getReturnType();
+ memberTypes.put(name, invocationHandlerReturnType(type));
+ members.put(name, method);
- Object defaultValue = method.getDefaultValue();
- if (defaultValue != null)
- memberDefaults.put(name, defaultValue);
+ Object defaultValue = method.getDefaultValue();
+ if (defaultValue != null) {
+ memberDefaults.put(name, defaultValue);
+ }
+ }
}
// Initialize retention, & inherited fields. Special treatment
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/AnnotationWithLambda.java Thu Jun 09 09:33:37 2016 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8147585
+ * @summary Check Annotation with Lambda, with or without parameter
+ * @run testng AnnotationWithLambda
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.function.Consumer;
+
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+public class AnnotationWithLambda {
+
+ @Test
+ void testAnnotationWithLambda() {
+ Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods();
+ for (Method method : methods) {
+ assertTrue((method.isAnnotationPresent(LambdaWithParameter.class)) &&
+ (method.isAnnotationPresent(LambdaWithoutParameter.class)));
+
+ }
+ }
+
+ static class MethodsWithAnnotations {
+
+ @LambdaWithParameter
+ @LambdaWithoutParameter
+ public void testAnnotationLambda() {
+ }
+ }
+}
+
+@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");
+}
+