RFR 8073056: Repeating annotations throws java.security.AccessControlException with a SecurityManager

Peter Levart peter.levart at gmail.com
Thu Feb 26 22:04:15 UTC 2015


On 02/26/2015 10:27 PM, Peter Levart wrote:
>
> On 02/26/2015 05:34 PM, Mandy Chung wrote:
>>> The problem is with the default method 
>>> AnnotatedElement::getDeclaredAnnotationsByType. If someone has an 
>>> external implementation of AnnotatedElement (and one of the lessons 
>>> from adding these methods in 8 was that there are other 
>>> implementations) then if that external implementation haven’t added 
>>> getDeclaredAnnotationsByType they will call into our 
>>> AnnotationSupport. This is all fine if that external representation 
>>> of AnnotatedElement uses our representation of Annotations, with 
>>> Proxies and all. But I suspect that the conditions that would end up 
>>> taking the non-proxy code path in the patch, will already fail in 
>>> the check:
>>>
>>>               AnnotationType annoType = 
>>> AnnotationType.getInstance(containerClass);
>>>               if (annoType == null)
>>>                   throw invalidContainerException(container, null);
>>>
>>> So what is the best thing to do here if the annotation is not Proxy 
>>> based and is coming from an implementation of the AnnotatedElement 
>>> interface that we don’t control and that is missing the methods 
>>> added in 8?
>>
>> I did a quick search on my corpus and find only one reference to
>> sun.reflect.annotation.AnnotationType.  Looks like external 
>> implementation
>> doesn't get pass this. 
>
> Now I'm missing something. Why would a custom non-Proxy based 
> annotation not pass the above code? I don't see anything in 
> AnnotationType implementation that would be dependent on annotation 
> implementation to be a Proxy. AnnotationType only deals with the 
> annotation type, which is an interface, not with implementation.

I verified this with the following code:


import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;

@CustomAnnTest.Containee("a")
@CustomAnnTest.Containee("b")
@CustomAnnTest.Containee("c")
public class CustomAnnTest {

     @Retention(RetentionPolicy.RUNTIME)
     @Repeatable(Container.class)
     public @interface Containee {
         String value();
     }

     @Retention(RetentionPolicy.RUNTIME)
     public @interface Container {
         Containee[] value();
     }

     public static class MyElement implements AnnotatedElement {
         @Override
         public <T extends Annotation> T getAnnotation(Class<T> 
annotationClass) {
             for (Annotation ann : getDeclaredAnnotations()) {
                 if (ann.annotationType() == annotationClass) {
                     return annotationClass.cast(ann);
                 }
             }
             return null;
         }

         @Override
         public Annotation[] getAnnotations() {
             return getDeclaredAnnotations();
         }

         @Override
         public Annotation[] getDeclaredAnnotations() {
             return new Annotation[] {
                 new MyContainer(
                     new MyContainee("A"),
                     new MyContainee("B"),
                     new MyContainee("C")
                 )
             };
         }

         static class MyContainee implements Containee {
             final String value;

             MyContainee(String value) {
                 this.value = value;
             }

             @Override
             public String value() {
                 return value;
             }

             @Override
             public Class<? extends Annotation> annotationType() {
                 return Containee.class;
             }

             @Override
             public String toString() {
                 return "@" + annotationType().getName() + "(value=" + 
value + ")";
             }
         }

         static class MyContainer implements Container {
             final Containee[] value;

             MyContainer(Containee ... value) {
                 this.value = value;
             }

             @Override
             public Containee[] value() {
                 return value;
             }

             @Override
             public Class<? extends Annotation> annotationType() {
                 return Container.class;
             }

             @Override
             public String toString() {
                 return "@" + annotationType().getName() + "(value=" + 
Arrays.toString(value) + ")";
             }
         }
     }

     static void test(AnnotatedElement ae) {
         System.out.println(ae + ":");
System.out.println(Arrays.toString(ae.getDeclaredAnnotations()));
         System.out.println(ae.getAnnotation(Container.class));
         System.out.println(ae.getAnnotation(Containee.class));
System.out.println(Arrays.toString(ae.getDeclaredAnnotationsByType(Containee.class)));
         System.out.println();
     }

     public static void main(String[] args) {
         test(CustomAnnTest.class);
         test(new MyElement());
     }
}



... it works without problems and prints the expected:


class jdk.test.CustomAnnTest:
[@jdk.test.CustomAnnTest$Container(value=[@jdk.test.CustomAnnTest$Containee(value=a), 
@jdk.test.CustomAnnTest$Containee(value=b), 
@jdk.test.CustomAnnTest$Containee(value=c)])]
@jdk.test.CustomAnnTest$Container(value=[@jdk.test.CustomAnnTest$Containee(value=a), 
@jdk.test.CustomAnnTest$Containee(value=b), 
@jdk.test.CustomAnnTest$Containee(value=c)])
null
[@jdk.test.CustomAnnTest$Containee(value=a), 
@jdk.test.CustomAnnTest$Containee(value=b), 
@jdk.test.CustomAnnTest$Containee(value=c)]

jdk.test.CustomAnnTest$MyElement at 3764951d:
[@jdk.test.CustomAnnTest$Container(value=[@jdk.test.CustomAnnTest$Containee(value=A), 
@jdk.test.CustomAnnTest$Containee(value=B), 
@jdk.test.CustomAnnTest$Containee(value=C)])]
@jdk.test.CustomAnnTest$Container(value=[@jdk.test.CustomAnnTest$Containee(value=A), 
@jdk.test.CustomAnnTest$Containee(value=B), 
@jdk.test.CustomAnnTest$Containee(value=C)])
null
[@jdk.test.CustomAnnTest$Containee(value=A), 
@jdk.test.CustomAnnTest$Containee(value=B), 
@jdk.test.CustomAnnTest$Containee(value=C)]




More information about the core-libs-dev mailing list