< 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 >