Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning: File for type '[Insert class here]' created in the last round will not be subject to annotation processing

Tags:

java

java-7

I switched an existing code base to Java 7 and I keep getting this warning:

warning: File for type '[Insert class here]' created in the last round 
  will not be subject to annotation processing.

A quick search reveals that no one has hit this warning.

It's not documented in the javac compiler source either:

From OpenJDK\langtools\src\share\classes\com\sun\tools\javac\processing\JavacFiler.java

private JavaFileObject createSourceOrClassFile(boolean isSourceFile, String name) throws IOException {
    checkNameAndExistence(name, isSourceFile);
    Location loc = (isSourceFile ? SOURCE_OUTPUT : CLASS_OUTPUT);
    JavaFileObject.Kind kind = (isSourceFile ?
                                JavaFileObject.Kind.SOURCE :
                                JavaFileObject.Kind.CLASS);

    JavaFileObject fileObject =
        fileManager.getJavaFileForOutput(loc, name, kind, null);
    checkFileReopening(fileObject, true);

    if (lastRound) // <-------------------------------TRIGGERS WARNING
        log.warning("proc.file.create.last.round", name);

    if (isSourceFile)
        aggregateGeneratedSourceNames.add(name);
    else
        aggregateGeneratedClassNames.add(name);
    openTypeNames.add(name);

    return new FilerOutputJavaFileObject(name, fileObject);
}

What does this mean and what steps can I take to clear this warning?

Thanks.

like image 331
user1324792 Avatar asked Apr 10 '12 18:04

user1324792


2 Answers

The warning

warning: File for type '[Insert class here]' created in the last round will not be subject to annotation processing

means that your were running an annotation processor creating a new class or source file using a javax.annotation.processing.Filer implementation (provided through the javax.annotation.processing.ProcessingEnvironment) although the processing tool already decided its "in the last round".

This may be problem (and thus the warning) because the generated file itself may contain annotations being ignored by the annotation processor (because it is not going to do a further round).

The above ought to answer the first part of your question

What does this mean and what steps can I take to clear this warning?

(you figured this out already by yourself, didn't you :-))

What possible steps to take? Check your annotation processors:

1) Do you really have to use filer.createClassFile / filer.createSourceFile on the very last round of the annotaion processor? Usually one uses the filer object inside of a code block like

for (TypeElement annotation : annotations) {
...
} 

(in method process). This ensures that the annotation processor will not be in its last round (the last round always being the one having an empty set of annotations).

2) If you really can't avoid writing your generated files in the last round and these files are source files, trick the annotation processor and use the method "createResource" of the filer object (take "SOURCE_OUTPUT" as location).

like image 162
Hille Avatar answered Nov 07 '22 06:11

Hille


In OpenJDK test case this warning produced because processor uses "processingOver()" to write new file exactly at last round.

public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) {
        if (renv.processingOver()) { // Write only at last round
            Filer filer = processingEnv.getFiler();
            Messager messager = processingEnv.getMessager();
            try {
                JavaFileObject fo = filer.createSourceFile("Gen");
                Writer out = fo.openWriter();
                out.write("class Gen { }");
                out.close();
                messager.printMessage(Diagnostic.Kind.NOTE, "File 'Gen' created");
            } catch (IOException e) {
                messager.printMessage(Diagnostic.Kind.ERROR, e.toString());
            }
        }
        return false;
    }

I modified original example code a bit. Added diagnostic note "File 'Gen' created", replaced "*" mask with "org.junit.runner.RunWith" and set return value to "true". Produced compiler log was:

Round 1:
input files: {ProcFileCreateLastRound}
annotations: [org.junit.runner.RunWith]
last round: false
Processor AnnoProc matches [org.junit.runner.RunWith] and returns true.
Round 2:
input files: {}
annotations: []
last round: true
Note: File 'Gen' created
Compilation completed successfully with 1 warning
0 errors
1 warning
Warning: File for type 'Gen' created in the last round will not be subject to annotation processing.

If we remove my custom note from log, it's hard to tell that file 'Gen' was actually created on 'Round 2' - last round. So, basic advice applies: if in doubt - add more logs.


Where is also a little bit of useful info on this page: http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

Read section about "ANNOTATION PROCESSING" and try to get more info with compiler options:
-XprintProcessorInfo Print information about which annotations a processor is asked to process.
-XprintRounds Print information about initial and subsequent annotation processing rounds.

like image 37
Vadim Ponomarev Avatar answered Nov 07 '22 06:11

Vadim Ponomarev