Java 警告:文件类型为';[在此插入类]';在上一轮中创建的将不接受注释处理
我将现有的代码库切换到Java 7,并不断收到以下警告:Java 警告:文件类型为';[在此插入类]';在上一轮中创建的将不接受注释处理,java,java-7,Java,Java 7,我将现有的代码库切换到Java 7,并不断收到以下警告: warning: File for type '[Insert class here]' created in the last round will not be subject to annotation processing. 快速搜索显示没有人点击此警告 javac编译器源代码中也没有记录: 来自OpenJDK\langtools\src\share\classes\com\sun\tools\javac\processi
warning: File for type '[Insert class here]' created in the last round
will not be subject to annotation processing.
快速搜索显示没有人点击此警告
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);
}
private JavaFileObject createSourceOrClassFile(布尔isSourceFile,字符串名)引发IOException{
CheckName和Existence(名称,isSourceFile);
位置loc=(isSourceFile?源输出:类输出);
JavaFileObject.Kind种类=(isSourceFile?
JavaFileObject.Kind.SOURCE:
JavaFileObject.Kind.CLASS);
JavaFileObject文件对象=
getJavaFileForOutput(loc、name、kind、null);
CheckFileResopening(fileObject,true);
如果(lastRound)/我仔细查看了java 7编译器选项,发现了以下内容:
-隐式:{class,none}
控制隐式加载的源文件的类文件的生成。若要自动生成类文件,请使用-implicit:class。若要禁止生成类文件,请使用-implicit:none。如果未指定此选项,默认值为自动生成类文件。在这种情况下,如果有此类类文件,编译器将发出警告也在执行批注处理时生成。如果显式设置此选项,则不会发出警告。请参阅搜索类型
您是否可以尝试隐式声明类文件。在该警告中,由于处理器在最后一轮中使用“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;
}
如果我们从日志中删除我的自定义注释,很难说文件“Gen”实际上是在“第2轮”(最后一轮)上创建的。因此,基本建议适用:如果有疑问,请添加更多日志
这里还有一些有用的信息:
阅读有关“注释处理”的部分,并尝试使用编译器选项获取更多信息:
-XprintProcessorInfo
打印有关要求处理器处理哪些批注的信息。
-XprintRounds打印有关初始和后续注释处理循环的信息。警告
警告:上一轮中创建的“[Insert class here]”类型的文件
将不接受批注处理
这意味着您正在运行注释处理器,使用javax.annotation.processing.Filer实现(通过javax.annotation.processing.ProcessingEnvironment提供)创建新的类或源文件,尽管处理工具已经决定“在最后一轮中”
这可能是一个问题(因此也是一个警告),因为生成的文件本身可能包含被注释处理器忽略的注释(因为它不会进行下一轮)
以上应该回答你问题的第一部分
这意味着什么?我可以采取什么步骤来清除此警告
(你自己已经弄明白了,不是吗:-)
要采取哪些可能的步骤?请检查批注处理器:
1) 在注释处理器的最后一轮中,您真的必须使用filer.createClassFile/filer.createSourceFile吗?通常在代码块中使用filer对象,如
for (TypeElement annotation : annotations) {
...
}
(在方法过程中)。这确保注释处理器不会处于最后一轮(最后一轮始终是注释集为空的一轮)
2) 如果您确实无法避免在上一轮中写入生成的文件,并且这些文件是源文件,请欺骗注释处理器,并使用filer对象的方法“createResource”(以“source_OUTPUT”作为位置).当我读到这个问题时,我最初认为这是因为无法关闭文件。为了测试这一点,我创建了一个简单的处理器,创建、写入但没有关闭文件。我运行了它。它给出了类似但不同的警告。这里的问题是注释处理,而不是类生成。这个特定的代码库取决于类生成。指定-隐式:由于没有生成类,因此没有实际中断生成。-隐式:类对警告没有影响。是的,在我问问题之前就这样做了(可能应该将其放在上面的信息中)。它似乎没有产生任何有用的结果。当它进入最后一轮时,它说没有更多的输入文件,然后发送警告。你能分离出产生此警告的最小测试用例吗?也许可以借助上面的编译器选项。我在OpenJDK源代码中找到了一个测试用例:文件夹“openjdk\langtools\test\tools\javac\diags\examples\ProcFileCreateLastRound"。但我仍然无法理解为什么会在那个地方放置警告。我在原始答案中添加了您问题的可能原因。如果是其他原因,则在看到测试用例之前,我无法告诉您更多。这很可能是一个。在某些方面,我们会在发送文件之前检查处理是否已结束,可能是由于FileRexception of多次打开同一文件。
for (TypeElement annotation : annotations) {
...
}