1 Reply Latest reply: Jun 26, 2007 4:29 AM by 608410 RSS

    annotations' inheritance, polymorphism, 'cycle detected' limitations are...

    843793
      ... giving me a headache.

      Hi all,

      What I would like to do is specify access rights on some methods, like so:
      @Or({     @Role("Administrator"), 
               @Role("Engineer")
          })
      public void someMethod();
      This reads like "all persons having the administrator role or the Engineer role have access to the someMethod() method".

      The annotations would then look like this:
      @interface Role {
          String value();
      }
      
      @interface Or {
           Role[] values();
      }
      This works fine. However, when I want to add some more complexity, things fall apart. The following for example does not work:
      @Or(      {     @Role("Administrator"), 
                @And(      {     @Role("Engineer"),
                                @Role("Tester")
                     })
           })
      public void someMethod();
      The reason this cannot work is that annotations don't support inheritance - so you cannot create a common super type for both the @Role and the @And annotation, and so the values() method of the @Or annotation cannot return a array that can contain both @Role and @And annotations.

      So I tried something different. The idea was to do something like this:
      @Check( name="Or" 
           children={     @Check(name="Administrator"), 
                     @Check(     name="And"
                          children{      @Check(name="Engineer"),
                                    @Check(name="Tester")
                               })
                 })
      public void someMethod();
      But this too is not possible. Not only is there the problem about how to specify a default value for the children(), the compiler is also giving me the following exception: "Cycle detected: the annotation type Check cannot contain attributes of the annotation type itself". Why is that?

      Here's that annotation definition:
      @interface Check {
          String name() default "";
          Check[] children() default???; 
      }
      Anybody has an idea? Or should I leave this track altogether, and try to solve it without annotations? Thanks!
        • 1. Re: annotations' inheritance, polymorphism, 'cycle detected' limitations ar
          608410
          >
          But this too is not possible. Not only is there the
          problem about how to specify a default value for the
          children(), the compiler is also giving me the
          following exception: "Cycle detected: the annotation
          type Check cannot contain attributes of the
          annotation type itself". Why is that?
          its not allowed because the annotations were designed very conservatively, and there are some cases where if it were allowed, things start to get really nasty. The annotation spec designers just avoided all the nasty cases by not allowing anything that got remotely close to them.

          >
          >
          Anybody has an idea? Or should I leave this track
          altogether, and try to solve it without annotations?
          Thanks!
          Go vote for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6264216 and maybe one day some of these safe cases (biut close to nasty cases) will be allowed.

          Yep, annotations seem to offer so much, but suddenly you find they don't go quite far enough to get you home, nearly, but not quite. Sad.

          So meantime, think laterally.

          You could make your annotation member a single string, and use a tiny language to define your constraints,. In JDK6 you might even be able to set the value to a javascript expression and use the java scripting framework to interpret it. But then you wouldn't get compile time syntax checking. But face it, even if your examples worked, thy are getting pretty tedious, worse even than xml, so maybe a tiny language is better in this case.

          Bruce