1

I wrote an annotation processor (to copy some java sources in my compiling directory). I was surprised to see that only the files specified on the javac command line are processed by my annotation processor. I'm obviously missing something.

Here is a minimal example:

sandbox.Aproc:

(...)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class AProc extends AbstractProcessor{   
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return Arrays.asList( Include.class ).stream().
            map(C->C.getName()).
            collect(Collectors.toSet())
            ;
        }
    
    private void copySource(final javax.lang.model.element.Element element)
        {
        if(element==null || element.getKind()!=ElementKind.CLASS) return;
        final String thisDir = System.getProperty("user.dir");
        System.err.println("##Visit " + element);
        (...)
        }
    
    @Override
    public boolean process(final Set<? extends TypeElement> annotations,
        final RoundEnvironment roundEnv
        ) {             
        roundEnv.getElementsAnnotatedWith(Include.class).stream().
            filter(E->E.getKind()==ElementKind.CLASS).
            filter(E-> E.getAnnotation(Include.class) !=null).
            forEach(E->{                    
                copySource(E);
                });
        
        return true;
       }
    }

sandbox/Test.java This class uses Test2 so I expect this Test2 will also be visited by the processor.

package sandbox;
@Include
public class Test {
Test2 get() { return new Test2();}
}

sandbox/Test2.java

package sandbox;
@Include
public class Test2 {
}

sandbox/Include.java

(...)
package sandbox;
@Retention(RUNTIME)
@Target({ ElementType.TYPE })
public @interface Include
    {
    }

The annotation processor is packaged in a jar with sandbox.AProc in TMP/META-INF/services/javax.annotation.processing.Processor

When I compile with both Test.java and Test2.java they both appear in the processor logs.

$ javac -cp .:annot.jar  -d TMP sandbox/Test.java sandbox/Test2.java
##Visit sandbox.Test
##Visit sandbox.Test2

but if I only compile sandbox/Test.java, Test2 is compiled but ignored by the processor.

$ javac -cp .:annot.jar  -d TMP sandbox/Test.java 
##Visit sandbox.Test
warning: Implicitly compiled files were not subject to annotation processing.
  Use -proc:none to disable annotation processing or -implicit to specify a policy for implicit compilation.
1 warning

(I'm not sure about the warning, using -implicit:class hide the problem).

How can I tell the processor to visit all the classes without specifying them on the javac command line ?

Pierre
  • 34,472
  • 31
  • 113
  • 192
  • Probably not possible, the documentation, at least for Java 8, says implicitly compiled files aren't subject to annotation processing, and there doesn't seem to be any option to make them subject, other than specifiying them explicitely. See https://stackoverflow.com/questions/23520975/can-someone-provide-an-example-of-how-javacs-implicit-option-works – kutschkem Jan 26 '23 at 10:51

0 Answers0