4 Replies Latest reply: Jan 18, 2010 10:39 AM by 843793 RSS

    Printing annotations; readability of package annotations

    843793
      Hey,

      A couple of JSR 269 things. First, is there a way to get correct source code for an annotation object returned by Element.getAnnotation for printing to the writer of a source file, or do you have to get the AnnotationMirror for that? When appropriate I tend to use plain annotation objects instead of mirrors since they're more convenient to work with, and a convenient way to get compilable code for them would be nice. As an aside, Elements.getConstantExpression doesn't seem to throw a IllegalArgumentException when "the argument is not a primitive value or string", but rather the toString of it, which doesn't give compilable code for at least annotation objects (hey I had to try, despite what the doc says)

      Next, related to the reason I'm tinkering about with printing annotations in the first place. As far as I can see invoking getAnnotation and getAnnotationMirrors on package elements always return nothing if the corresponding package-info.java source files are not on the list of source files to be compiled being given to javac. This is different from annotations on types, which may be readable even when they're not being compiled (depending on Xprefer and the retention policy of the annotations, of course) if you somehow get their element. Is this the correct behavior? I'm using 6u10.

      Thanks in advance.
        • 1. Re: Printing annotations; readability of package annotations
          608410
          thormick wrote:
          Hey,

          A couple of JSR 269 things. First, is there a way to get correct source code for an annotation object returned by Element.getAnnotation for printing to the writer of a source file, or do you have to get the AnnotationMirror for that? When appropriate I tend to use plain annotation objects instead of mirrors since they're more convenient to work with, and a convenient way to get compilable code for them would be nice. As an aside, Elements.getConstantExpression doesn't seem to throw a IllegalArgumentException when "the argument is not a primitive value or string", but rather the toString of it, which doesn't give compilable code for at least annotation objects (hey I had to try, despite what the doc says)
          You might like to look at project Hickory 's [Prism |https://hickory.dev.java.net/nonav/apidocs/index.html?net/java/dev/hickory/prism/package-summary.html] mechanism as sweet spot between Annotations returned from getAnnotation, and AnnotationMirror.

          In regards to extracting the source code, I wouldn't expect an Annotation returned by Element.getAnnotation to necessarily have a toString() method that returned the source code. And there is no other defined method that would. Many of the Element implementations do return the effective source code when their toString() is called, though again that is not defined.

          If the AnnotationMirror.toString() gives you what you want, but you would like the convenience of an Annotation returned by Element.getAnnotation, then have a try of the Prism mechanism, generate a Prism class for your know annotation, and from that you can get the values in a convenient form (more convenient than a Annotation), and still access the underlying AnnotationMirror.

          Bruce
          • 2. Re: Printing annotations; readability of package annotations
            843793
            thormick wrote:
            Hey,

            A couple of JSR 269 things. First, is there a way to get correct source code for an annotation object returned by Element.getAnnotation for printing to the writer of a source file, or do you have to get the AnnotationMirror for that?
            The printing utility included as part of JSR 269, javax.lang.model.util.Elements.printElements acts on Elements, not annotations; although it will print annotation information.

            Without taking imports into account, correct source code will need to use fully qualified names, which may not be what you want.
            When appropriate I tend to use plain annotation objects instead of mirrors since they're more convenient to work with, and a convenient way to get compilable code for them would be nice. As an aside, Elements.getConstantExpression doesn't seem to throw a IllegalArgumentException when "the argument is not a primitive value or string", but rather the toString of it, which doesn't give compilable code for at least annotation objects (hey I had to try, despite what the doc says)
            Yep, that is bug

            6517779 javax.lang.model.util.Elements.getConstantExpression() doesn't throw any exception

            >
            Next, related to the reason I'm tinkering about with printing annotations in the first place. As far as I can see invoking getAnnotation and getAnnotationMirrors on package elements always return nothing if the corresponding package-info.java source files are not on the list of source files to be compiled being given to javac. This is different from annotations on types, which may be readable even when they're not being compiled (depending on Xprefer and the retention policy of the annotations, of course) if you somehow get their element. Is this the correct behavior? I'm using 6u10.
            It is certainly possible that the implementation's handling of a package-info.class may be a bit buggy compared to handling the source version. Note that unless the package annotations have at least class file retention, there might not be any package-info.class file.
            • 3. Re: Printing annotations; readability of package annotations
              843793
              brucechapman wrote:
              -snip-
              If the AnnotationMirror.toString() gives you what you want, but you would like the convenience of an Annotation returned by Element.getAnnotation, then have a try of the Prism mechanism, generate a Prism class for your know annotation, and from that you can get the values in a convenient form (more convenient than a Annotation), and still access the underlying AnnotationMirror.

              Bruce
              Oh thanks! I was aware of Hickory but haven't looked at it properly.
              j.d.darcy wrote:

              It is certainly possible that the implementation's handling of a package-info.class may be a bit buggy compared to handling the source version. Note that unless the package annotations have at least class file retention, there might not be any package-info.class file.
              That was my first thought too, that it's something with how package-info.class is handled, but I've also noticed the same result on a fresh, partial compile. I cleaned out the class destination directory and with "sourcepath" set I compiled only a single class so that my annotation processor would get triggered, but it still couldn't see any annotations I had placed on the package while it could see those on other classes. Yeah, I know about retention, this happens no matter what it's set to.

              Well thanks either way. I think I'll rework my processor so it doesn't rely on package annotations being readable when compiling classes.
              • 4. Re: Printing annotations; readability of package annotations
                843793
                I have run into the same issue with my annotation processor not being able to see package annotations that are declared in the package-info.java file. The Elcipse IDE says that package annotations must go in package-info.java but I don't see how I can make use of these annotations. Is this info treated as implicitly compiled and not subject to annotaiton processing? If you specify the package-info.java file on the command-line then the processor can see these files, but this is not a viable option.