4 Replies Latest reply: Sep 2, 2008 7:11 AM by 843793 RSS

    annotation processor simple test

    843793
      Hello!

      I am trying to write a simple test Annotation Processor, using the Pluggable Annotation Processing API (JSR 269).

      I use the following annotation:
      package proactive;
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.TYPE)
      public @interface ActiveObject {  }
      and the following processor for it:
      package jsr269;
      
      import java.util.Set;
      
      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.ProcessingEnvironment;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.annotation.processing.SupportedSourceVersion;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;
      import com.sun.source.util.TreePath;
      import com.sun.source.util.Trees;
      
      
      import proactive.ActiveObject;
      
      
      @SupportedSourceVersion(SourceVersion.RELEASE_6)
      //cannot use ActiveObject.class.getName() the value must be a constant expression BLEAH!
      @SupportedAnnotationTypes( { "proactive.ActiveObject"} ) 
      public class ProActiveProcessor extends AbstractProcessor {
           
           @Override
           public synchronized void init(ProcessingEnvironment processingEnv) {
                System.out.println("initialising...");
                super.init(processingEnv);
           }
      
           @Override
           public boolean process(Set<? extends TypeElement> annotations,
                     RoundEnvironment roundEnv) {
      
                      System.out.println("Starting to process the annotations...");
                
                Set<? extends Element> annotatedElements = roundEnv.
                     getElementsAnnotatedWith(ActiveObject.class);
                
                for (Element element : annotatedElements) {
                     // scan the nodes on the tree recursively
                     System.out.println("Will process the element" + element.getSimpleName() );
                }
                
                return true;
           }
           
      }
      I build the processor and annotation, and start a javac at the console, like this:
      javac -processorpath ../../AnnotationTest/bin/ -processor jsr269.ProActiveProcessor TestThis.java
      The test class TestThis.java is:
      @ActiveObject
      public class TestThis implements Serializable{
           
           @ActiveObject
           public class Tataia {
                public Tataia(int n) {}
                private volatile List<Object> _someLocks;
                private synchronized void doNothingSynchronized() {}
                private final int dontOverrideMe() { return 0; }
                
                public int _counter;
                
                //public int getCounter() { return _counter; }
                
                public void setCounter(int counter) { _counter = counter; }
           }
      }
      When I run javac with the annotation processor given as an argument, I get the following output:
      bash-3.2$ javac -processorpath ../../AnnotationTest/bin/ -processor jsr269.ProActiveProcessor TestThis.java
      initialising...
      So, if we follow the interaction steps described in the Processor javadoc, the processor gets created, the init method is called, but then the process method never gets called.

      I've modified the ProActiveProcessor class, like this:
      public class ProActiveProcessor extends AbstractProcessor {
           
           // the annotations for which this factory provides processors
           private static final Set<String> _supportedAnnotations =
                Collections.singleton(
                          ActiveObject.class.getName() 
                          );
           
           @Override
           public synchronized void init(ProcessingEnvironment processingEnv) {
                System.out.println("initialising...");
                super.init(processingEnv);
           }
           
           @Override
           public Set<String> getSupportedAnnotationTypes() {
                System.out.println("I support the annotation:" + _supportedAnnotations.iterator().next());
                return _supportedAnnotations;
           }
      
           @Override
           public boolean process(Set<? extends TypeElement> annotations,
                     RoundEnvironment roundEnv) {
                
                System.out.println("Starting to process the annotations...");
                
                Trees trees = Trees.instance(processingEnv);
                
                Set<? extends Element> annotatedElements = roundEnv.
                     getElementsAnnotatedWith(ActiveObject.class);
                
                for (Element element : annotatedElements) {
                     // scan the nodes on the tree recursively
                     //TreePath treePath = trees.getPath(element);
                     System.out.println("Will process the element" + element.getSimpleName() );
                     //visitor.scan( treePath , _trees);
                }
                
                return true;
           }
           
      }
      the output is:
      initialising...
      I support the annotation:proactive.ActiveObject
      So, the problem seems to be that the process method never gets called! What do you think is the problem?
      I am using JDK version 1.6.0_02.
        • 1. Re: annotation processor simple test
          843793
          Hmm, I don't see that issue running JDK 6 update 5. To get more information about what is going on, use the -XprintRounds and -XprintProcessorInfo options to javac.
          • 2. Re: annotation processor simple test
            608410
            I suspect you haven't given us all the information.

            The source for TestThis doesn't specify a package, so either you didn't post that line, or TestThis is in the default package.

            If it is indeed in the default package (and your command line supports this), then you would get the results you are seeing because you don't import or qualify the annotation ActiveObject. However you would also see an error from the compiler about the symbol ActiveObject not being found.

            Specifically the compiler would be looking for a processor for ActiveObject (fully qualified) and all it can find is one for proactive.ActiveObject (fully qualified)

            Did you get a compiler error that you did not post here?

            or did you have a package statement in ActiveObject that you didn't post here?

            Bruce
            • 3. Re: annotation processor simple test
              843793
              TestThis is indeed in the default package.

              No, ActiveObject is imported, otherwise the compiler would have complained. I do not have any other compiler error that I didn't specify here.

              The problem was with the code from the process method. I now use the following code:
                      private static final String ACTIVE_OBJECT_ANNOTATION = "org.objectweb.proactive.annotation.activeobject.ActiveObject";
                   private static final String MIGRATION_SIGNAL_ANNOTATION = "org.objectweb.proactive.annotation.migration.MigrationSignal"; 
                   
                   @Override
                   public boolean process(Set<? extends TypeElement> annotations,
                             RoundEnvironment roundEnv) {
                        
                        if (annotations.isEmpty()) {
                             // called with no annotations
                             return true;
                        }
                        
                        for (TypeElement annotationElement : annotations) {
                             if ( annotationElement.getQualifiedName().toString().equals(ACTIVE_OBJECT_ANNOTATION) ) {
                                  processActiveObjectAnnotation(roundEnv, annotationElement);
                             } else
                             if ( annotationElement.getQualifiedName().toString().equals(MIGRATION_SIGNAL_ANNOTATION) ) {
                                  processMigrationSignalAnnotation(roundEnv, annotationElement);
                             }
                        }
                        
                        return true;
                   }
              it works just fine.
              Thanks for your help! Sorry for my late reply...
              • 4. Re: annotation processor simple test
                843793
                Hi, fbratu
                I am also working for the same from long time . could you please help me out .
                Really it would be the great help for me. could you send me the complete source code and the compilation command.
                my mail id is nanimca@gmail.com

                Thanks and Regards,
                uday Kiran D