18

既存のコード ベースを 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\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);
}

これは何を意味し、この警告をクリアするにはどのような手順を実行すればよいですか?

ありがとう。

4

3 に答える 3

5

警告

警告: 前回のラウンドで作成された「[ここにクラスを挿入]」タイプのファイルは、アノテーション処理の対象になりません

javax.annotation.processing.Filer 実装 (javax.annotation.processing.ProcessingEnvironment を介して提供される) を使用して新しいクラスまたはソース ファイルを作成する注釈プロセッサを実行していたことを意味しますが、処理ツールは既に「最後のラウンドで」それを決定しました。 .

生成されたファイル自体に、注釈プロセッサによって無視される注釈が含まれている可能性があるため、これは問題になる可能性があります (したがって、警告)。

上記はあなたの質問の最初の部分に答えるはずです

これは何を意味し、この警告をクリアするにはどのような手順を実行すればよいですか?

(あなたはすでにこれを自分で考え出しましたね:-))

どのような手順を実行できますか? アノテーション プロセッサを確認します。

1) 注釈プロセッサの最後のラウンドで本当に filer.createClassFile / filer.createSourceFile を使用する必要がありますか? 通常、次のようなコード ブロック内でファイラー オブジェクトを使用します。

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

(メソッド処理中)。これにより、注釈プロセッサが最後のラウンドにならないことが保証されます (最後のラウンドは、常に空の注釈セットを持つラウンドです)。

2) 最終ラウンドで生成されたファイルを書き込むことを本当に避けられず、これらのファイルがソース ファイルである場合は、注釈プロセッサをだまして、ファイラー オブジェクトのメソッド「createResource」を使用します (「SOURCE_OUTPUT」を場所として使用します)。

于 2013-04-19T22:38:09.487 に答える
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;
    }

元のサンプル コードを少し変更しました。診断メモ「File 'Gen' created」を追加し、「*」マスクを「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.

ログからカスタム メモを削除すると、ファイル「Gen」が実際に「ラウンド 2」 (最後のラウンド) で作成されたことを伝えるのが難しくなります。したがって、基本的なアドバイスが適用されます。疑わしい場合は、ログを追加してください。


このページのどこにも少し役立つ情報があります: http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

「ANNOTATION PROCESSING」に関するセクションを読み、コンパイラ オプションを使用して詳細情報を取得して
ください
-XprintRounds初期および後続の注釈処理ラウンドに関する情報を出力します。

于 2012-04-12T10:08:15.130 に答える
0

私はjava7コンパイラのオプションをざっと見て、これを見つけました:

-implicit:{class、none} 暗黙的にロードされたソースファイルのクラスファイルの生成を制御します。クラスファイルを自動的に生成するには、-implicit:classを使用します。クラスファイルの生成を抑制するには、-implicit:noneを使用します。このオプションが指定されていない場合、デフォルトではクラスファイルが自動的に生成されます。この場合、アノテーション処理を行うときにそのようなクラスファイルが生成されると、コンパイラは警告を発行します。このオプションが明示的に設定されている場合、警告は発行されません。タイプの検索を参照してください。

ソース

クラスファイルを暗黙的に宣言してみてください。

于 2012-04-11T19:59:35.490 に答える