< prev index next >

src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java

Print this page

        

@@ -180,81 +180,42 @@
 
     /* Reflectively invoke the values-method of the given annotation
      * (container), cast it to an array of annotations and return the result.
      */
     private static <A extends Annotation> A[] getValueArray(Annotation container) {
-        try {
             // According to JLS the container must have an array-valued value
-            // method. Get the AnnotationType, get the "value" method and invoke
-            // it to get the content.
-
-            Class<? extends Annotation> containerClass = container.annotationType();
-            AnnotationType annoType = AnnotationType.getInstance(containerClass);
-            if (annoType == null)
-                throw invalidContainerException(container, null);
-            Method m = annoType.members().get("value");
-            if (m == null)
-                throw invalidContainerException(container, null);
-
-            if (Proxy.isProxyClass(container.getClass())) {
-                // Invoke by invocation handler
-                InvocationHandler handler = Proxy.getInvocationHandler(container);
-
+        // method. Usually the annotation will be implemented as a dynamic Proxy
+        // with AnnotationInvocationHandler as the invocation handler...
+        AnnotationInvocationHandler oneOfUs = AnnotationInvocationHandler.asOneOfUs(container);
+        if (oneOfUs != null) {
                 try {
                     // This will erase to (Annotation[]) but we do a runtime cast on the
                     // return-value in the method that call this method.
                     @SuppressWarnings("unchecked")
-                    A[] values = (A[]) handler.invoke(container, m, null);
+                A[] values = (A[]) oneOfUs.getValue(/* interned */ "value");
                     return values;
-                } catch (Throwable t) { // from InvocationHandler::invoke
+            } catch (Throwable t) {
                     throw invalidContainerException(container, t);
                 }
             } else {
                 // In theory there might be instances of Annotations that are not
                 // implemented using Proxies. Try to invoke the "value" element with
-                // reflection.
-
-                // Declaring class should be an annotation type
-                Class<?> iface = m.getDeclaringClass();
-                if (!iface.isAnnotation())
-                    throw new UnsupportedOperationException("Unsupported container annotation type.");
-                // Method must be public
-                if (!Modifier.isPublic(m.getModifiers()))
-                    throw new UnsupportedOperationException("Unsupported value member.");
-
-                // Interface might not be public though
-                final Method toInvoke;
-                if (!Modifier.isPublic(iface.getModifiers())) {
-                    if (System.getSecurityManager() != null) {
-                        toInvoke = AccessController.doPrivileged(new PrivilegedAction<Method>() {
-                            @Override
-                            public Method run() {
-                                Method res = ReflectionFactory.getReflectionFactory().leafCopyMethod(m);
-                                res.setAccessible(true);
-                                return res;
-                            }
-                        });
-                    } else {
-                        toInvoke = ReflectionFactory.getReflectionFactory().leafCopyMethod(m);
-                        toInvoke.setAccessible(true);
-                    }
-                } else {
-                    toInvoke = m;
-                }
+            // reflection using accessible Method object.
+            Method m = AnnotationType.getInstance(container.annotationType())
+                                     .accessibleMembers().get("value");
+            if (m == null)
+                throw invalidContainerException(container, null);
 
+            try {
                 // This will erase to (Annotation[]) but we do a runtime cast on the
                 // return-value in the method that call this method.
                 @SuppressWarnings("unchecked")
-                A[] values = (A[]) toInvoke.invoke(container);
-
+                A[] values = (A[]) m.invoke(container);
                 return values;
+            } catch (Throwable t) {
+                throw invalidContainerException(container, t);
             }
-        } catch (IllegalAccessException    | // couldn't loosen security
-                 IllegalArgumentException  | // parameters doesn't match
-                 InvocationTargetException | // the value method threw an exception
-                 ClassCastException e) {
-            throw invalidContainerException(container, e);
         }
     }
 
 
     private static AnnotationFormatError invalidContainerException(Annotation anno,
< prev index next >