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