警告:在最后一轮中创建的类型为"[在此处插入类]"的文件不会受到注释处理

use*_*792 15 java java-7

我将现有的代码库切换到Java 7,我不断收到此警告:

warning: File for type '[Insert class here]' created in the last round 
  will not be subject to annotation processing.
Run Code Online (Sandbox Code Playgroud)

快速搜索显示没有人发出此警告.

它没有在javac编译器源中记录:

从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);
}
Run Code Online (Sandbox Code Playgroud)

这意味着什么以及我可以采取哪些步骤来清除此警告?

谢谢.

Hil*_*lle 5

警告

警告:上一轮创建的类型“[在此处插入类]”的文件将不会进行注释处理

意味着您正在运行一个注释处理器,使用 javax.annotation.processing.Filer 实现(通过 javax.annotation.processing.ProcessingEnvironment 提供)创建一个新的类或源文件,尽管处理工具已经决定了它的“在最后一轮” .

这可能是问题(因此是警告),因为生成的文件本身可能包含注释处理器忽略的注释(因为它不会再进行一轮)。

以上应该回答你问题的第一部分

这是什么意思,我可以采取哪些步骤来清除此警告?

(你已经自己想通了,不是吗:-))

可以采取哪些措施?检查您的注释处理器:

1)你真的必须在最后一轮注释处理器上使用 filer.createClassFile / filer.createSourceFile 吗?通常在代码块中使用 filer 对象,例如

for (TypeElement annotation : annotations) {
...
} 
Run Code Online (Sandbox Code Playgroud)

(在方法过程中)。这确保注释处理器不会处于其最后一轮(最后一轮总是具有空注释集的一轮)。

2)如果你真的无法避免在最后一轮写入生成的文件并且这些文件是源文件,请欺骗注释处理器并使用文件管理器对象的方法“createResource”(以“SOURCE_OUTPUT”为位置)。


Vad*_*rev 2

OpenJDK 测试用例中,产生此警告是因为处理器在上一轮中使用“processingOver()”准确写入新文件。

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;
    }
Run Code Online (Sandbox Code Playgroud)

我对原始示例代码进行了一些修改。添加了诊断注释“文件'Gen'已创建”,用“org.junit.runner.RunWith”替换“*”掩码并将返回值设置为“true”。生成的编译器日志是:

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.
Run Code Online (Sandbox Code Playgroud)

如果我们从日志中删除我的自定义注释,则很难判断文件“Gen”实际上是在“第 2 轮”(上一轮)上创建的。因此,基本建议适用:如果有疑问 - 添加更多日志。


此页面上还有一些有用的信息: http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

阅读有关“注释处理”的部分,并尝试使用编译器选项获取更多信息:
-XprintProcessorInfo 打印有关要求处理器处理哪些注释的信息。
-XprintRounds打印有关初始和后续注释处理轮次的信息。