[JSR308] Other questions related to Annotation processing

Chester Chen CChen at ascentmedia.com
Thu Dec 18 16:24:33 EST 2008


Ok, Thank you. 
 
I actually tried, but did not get very far ( I got Null Pointer exception),  this might related to how the AnnotatedTypeFactory is initialized. 
 
Here is what I did, 
 
 First Try:
 
 AnnotatedTypeFactory  annotatedTypeFactory <file://m_annotatedTypeFactory/>  = new AnnotatedTypeFactory(processingEnv, null, null);       
 
  I got NullPointerException. 
 
2nd Try: 
 AnnotatedTypeFactory   <file://m_annotatedTypeFactory/> annotatedTypeFactory = new AnnotatedTypeFactory(processingEnv, null, treePath.getCompilationUnit());       
 
then
 in  Scanner
 
 
  @Override
    public R visitVariable(VariableTree tree, P p) {
 
            if (! tree.getType().getKind().equals(Tree.Kind.ANNOTATED_TYPE)) {
                return null;
            }
 
            AnnotatedTypeMirror type= m_annotatedTypeFactory.getAnnotatedType(tree);
 
            System.out.println("ResourceBundleScanner.visitVariable type = " + type);
            System.out.println("ResourceBundleScanner.visitVariable type.getElement() = " + type.getElement());
            System.out.println("ResourceBundleScanner.visitVariable type.getUnderlyingType() = " + type.getUnderlyingType());
            

        return super.visitVariable(tree, null);
 
    }
 
 
The exception is when processing something like this : 
 
           String var = ....
          
           public static void mymethod() {

                        if (StringUtils.isBlank(var)) {
 
                            @ErrorMessage(message="this is an annoation for local variable in {0}")
                            String errorcode = CommonsErrorCodeMessage.EC_1_BLANK_STRING;
                            
                            throw new ValidationException(errorcode, "getter");
                        }
            }
 
 
This is the exceptions for the 2nd try: 
 
   [javac6] An annotation processor threw an uncaught exception.
   [javac6] Consult the following stack trace for details.
   [javac6] java.lang.NullPointerException
   [javac6]  at checkers.types.TypeFromTree$TypeFromTypeTree.visitIdentifier(TypeFromTree.java:634)
   [javac6]  at checkers.types.TypeFromTree$TypeFromTypeTree.visitIdentifier(TypeFromTree.java:505)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:1698)
   [javac6]  at com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:52)
   [javac6]  at checkers.types.TypeFromTree$TypeFromTypeTree.visitAnnotatedType(TypeFromTree.java:519)
   [javac6]  at checkers.types.TypeFromTree$TypeFromTypeTree.visitAnnotatedType(TypeFromTree.java:505)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCAnnotatedType.accept(JCTree.java:2032)
   [javac6]  at com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:52)
   [javac6]  at checkers.types.AnnotatedTypeFactory.fromTreeWithVisitor(AnnotatedTypeFactory.java:361)
   [javac6]  at checkers.types.AnnotatedTypeFactory.fromTypeTree(AnnotatedTypeFactory.java:327)
   [javac6]  at checkers.types.AnnotatedTypeFactory.fromTypeTree(AnnotatedTypeFactory.java:323)
   [javac6]  at checkers.types.TypeFromTree$TypeFromMember.visitVariable(TypeFromTree.java:382)
   [javac6]  at checkers.types.TypeFromTree$TypeFromMember.visitVariable(TypeFromTree.java:370)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:724)
   [javac6]  at com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:52)
   [javac6]  at checkers.types.AnnotatedTypeFactory.fromTreeWithVisitor(AnnotatedTypeFactory.java:361)
   [javac6]  at checkers.types.AnnotatedTypeFactory.fromMember(AnnotatedTypeFactory.java:296)
   [javac6]  at checkers.types.AnnotatedTypeFactory.getAnnotatedType(AnnotatedTypeFactory.java:193)
   [javac6]  at checkers.types.AnnotatedTypeFactory.getAnnotatedType(AnnotatedTypeFactory.java:775)
   [javac6]  at com.managingdigitalcontent.pangu.commons.annotations.processor.ResourceBundleScanner.visitVariable(ResourceBundleScanner.java:135)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:724)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:159)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:778)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.visitIf(TreeScanner.java:233)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCIf.accept(JCTree.java:1127)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:159)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:778)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.visitIf(TreeScanner.java:234)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCIf.accept(JCTree.java:1127)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:159)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:778)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.visitIf(TreeScanner.java:233)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCIf.accept(JCTree.java:1127)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:159)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:778)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.visitEnhancedForLoop(TreeScanner.java:185)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCEnhancedForLoop.accept(JCTree.java:903)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:159)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:778)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.visitTry(TreeScanner.java:212)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCTry.accept(JCTree.java:1037)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:159)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:778)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.visitMethod(TreeScanner.java:143)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:678)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:80)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:98)
   [javac6]  at com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:132)
   [javac6]  at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:601)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:76)
   [javac6]  at com.sun.source.util.TreeScanner.scan(TreeScanner.java:90)
   [javac6]  at com.managingdigitalcontent.pangu.commons.annotations.processor.ResourceBundleProcessor.process(ResourceBundleProcessor.java:71)
   [javac6]  at com.managingdigitalcontent.pangu.commons.annotations.processor.PanguProcessor.process(PanguProcessor.java:41)
   [javac6]  at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:746)
   [javac6]  at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:675)
   [javac6]  at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:820)
   [javac6]  at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1029)
   [javac6]  at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:772)
   [javac6]  at com.sun.tools.javac.main.Main.compile(Main.java:393)
   [javac6]  at com.sun.tools.javac.main.Main.compile(Main.java:313)
   [javac6]  at com.sun.tools.javac.main.Main.compile(Main.java:304)
   [javac6]  at com.sun.tools.javac.Main.compile(Main.java:82)
   [javac6]  at com.sun.tools.javac.Main.main(Main.java:67)

 
 
 
 

-----Original Message-----
From: Artemus Harper [mailto:subanark at gmail.com]
Sent: Thursday, December 18, 2008 12:55 PM
To: Chester Chen
Cc: JSR 308 (Annotations) mailing list
Subject: Re: [JSR308] Other questions related to Annotation processing


If you use getUnderlyingType() you will end up with the definition of the class, and get annotation A. If you simply look at the annotations of fieldA (from AnnotatedTypeMirror) you will get annotation B. I would have to look at the implementation, but you might get annotation A for fieldA if its declaration was not annotated with any annotations. As usual try it and see what you get.

On Dec 18, 2008, at 12:30 PM, Chester Chen wrote:


Thanks for the further clarification. It is helpful.

But I am still confused by your original statement:

>"....you will get annotation A, not annotation B. The AnnotatedTypeMirror will (by default) annotate all uses of fieldA 
> with @B."


If I going through the AST tree node,

 1) I visit class ClsA, as for the Annotation, I got @A
 2) I visit class ClsB, visit the field A, ask field's annotation, I got @B
 3) I visit method ClsB.m, found method Select identified fieldA.

   if "the AnnotatedTypeFactory will copy the annotation from 
fieldA's declaration to its use", then identifier fieldA will has annotation of @B.

   If that's the case, do you mean by ""....you will get annotation A, not annotation B." then ?

Thanks

Chester
  

   

   



-----Original Message-----
From: Artemus Harper [ mailto:subanark at gmail.com]
Sent: Thu 12/18/2008 12:05 PM
To: Chester Chen
Cc: JSR 308 (Annotations) mailing list
Subject: Re: [JSR308] Other questions related to Annotation processing

No, I do mean B, not A. There is an annotation on the field, and one 
on the definition of the type of the field.
The tree:
private @B ClsA fieldA = new ClsA();
is a type of VariableTree, it has the annotation of @B

The tree:
fieldA.toString();
is a statement tree, that contains a MethodInvocationTree. The method 
select part of this tree is an IdentifierTree:
fieldA
This identifier doesn't and can't have any annotation declared on it. 
However, the AnnotatedTypeFactory will copy the annotation from 
fieldA's declaration to its use. If you want to change how annotations 
are inferred, then you should subclass the AnnotatedTypeFactory and 
supply your own implementation of the annotateImplicit methods. E.g. 
you could mark a variable use as being @Validated if validate() was 
called on an object.
On Dec 18, 2008, at 11:51 AM, Chester Chen wrote:

> Artemus,
>
>    Thanks for the detailed reply.
>
>    I did not follow your last point :
>
>     >"....you will get annotation A, not annotation B. The 
> AnnotatedTypeMirror will (by default) annotate all uses of fieldA 
> with @B."
>
>    do you mean to say
>
>     ....you will get annotation A, not annotation B. The 
> AnnotatedTypeMirror will (by default) annotate all uses of fieldA 
> with @A.
>
>   Any way, I will tries this out.
>
> Thanks
>
> Chester
> -----Original Message-----
> From: Artemus Harper [ mailto:subanark at gmail.com]
> Sent: Thursday, December 18, 2008 10:28 AM
> To: Chester Chen
> Cc: JSR 308 (Annotations) mailing list
> Subject: Re: [JSR308] Other questions related to Annotation processing
>
> You need to ask the AnnotatedTypeFactory for a AnnotatedTypeMirror 
> for the tree node. E.g.
> AnnotatedTypeMirror type = atypeFactory.getAnnotatedType(node);
>
> From AnnotatedTypeMirror you can use directSuperTypes() to get the 
> super types, or use any other method to get annotation information.
>
> Not every tree has an assoicated Element. In particular any tree 
> node within a method does not have an Element. However, you can use 
> getUnderlyingType() in AnnotatedTypeMirror to get the TypeMirror. 
> From there if the type is a DeclaredType (check with getKind()) you 
> can cast to DeclaredType and get its Element. Pass the Element back 
> into the AnnotatedTypeFactory to get the annotations.
>
> Note: doing this will give you the element of the declared type, not 
> the element of the declaration. E.g.
>
> @A public class ClsA { }
> public class ClsB {
>    private @B ClsA fieldA= new ClsA();
>    public void m() {
>        fieldA.toString();
>    }
> }
>
> If you use the above technique to get the Element, you will get 
> annotation A, not annotation B. The AnnotatedTypeMirror will (by 
> default) annotate all uses of fieldA with @B. In general you should 
> not ask   Element for annotations, as this ignores any implicit 
> annotations that might be added, and those that can only be added in 
> JSR-308 (e.g. class A extends @Anno B).
> On Dec 18, 2008, at 9:21 AM, Chester Chen wrote:
>
>> 1.  How do I traverse over an ancestors or referenced classes ?
>>
>>     Once I found the Tree node in the AST, how to I find the class, 
>> parent class and their annoation information ?
>>
>> 2.How I can get Element from a Tree Node ?
>>
>>
>> Thanks
>>
>> Chester
>>
>> _______________________________________________
>> JSR308 mailing list
>> JSR308 at lists.csail.mit.edu
>> https://lists.csail.mit.edu/mailman/listinfo/jsr308
>





-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.csail.mit.edu/pipermail/jsr308/attachments/20081218/4836d38d/attachment-0001.htm 


More information about the JSR308 mailing list