< prev index next >
src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java
Print this page
*** 180,260 ****
/* 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);
!
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);
return values;
! } catch (Throwable t) { // from InvocationHandler::invoke
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;
! }
// 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);
!
return values;
}
- } 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,
--- 180,221 ----
/* 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) {
// According to JLS the container must have an array-valued value
! // 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[]) oneOfUs.getValue(/* interned */ "value");
return values;
! } 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 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[]) m.invoke(container);
return values;
+ } catch (Throwable t) {
+ throw invalidContainerException(container, t);
}
}
}
private static AnnotationFormatError invalidContainerException(Annotation anno,
< prev index next >