Подтвердить что ты не робот

Внимание: файл для типа '[Insert class here]', созданный в последнем раунде, не будет обрабатываться аннотацией

Я переключил существующую базу кода на 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);
}

Что это значит и какие шаги я могу предпринять, чтобы очистить это предупреждение?

Спасибо.

4b9b3361

Ответ 1

В 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" был фактически создан в "Round 2" - последний раунд. Таким образом, применяются основные рекомендации: если есть сомнения - добавьте больше журналов.


Где также немного полезной информации на этой странице: http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

Прочтите раздел "ОБРАБОТКА АННОТАЦИИ" и попробуйте получить дополнительную информацию о параметрах компилятора:
-XprintProcessorInfo Распечатайте информацию о том, какие аннотации обрабатывается процессором.
-XprintRounds Печать информации о начальных и последующих циклах обработки аннотаций.

Ответ 2

Предупреждение

warning: Файл для типа '[Insert class here]', созданный в последнем раунде не будет обрабатываться аннотациями

означает, что у вас был обработчик аннотаций, создающий новый класс или исходный файл, используя реализацию javax.annotation.processing.Filer(предоставляемую через javax.annotation.processing.ProcessingEnvironment), хотя инструмент обработки уже решил, что он "в последний раунд".

Это может быть проблема (и, следовательно, предупреждение), потому что сам сгенерированный файл может содержать аннотации, игнорируемые обработчиком аннотаций (поскольку он не собирается делать следующий раунд).

Вышеупомянутое должно ответить на первую часть вашего вопроса.

Что это значит и какие шаги я могу предпринять, чтобы очистить это предупреждение?

(вы поняли это уже сами, не так ли: -))

Какие возможные шаги предпринять? Проверьте свои процессоры аннотаций:

1) Вам действительно нужно использовать filer.createClassFile/filer.createSourceFile в самом последнем раунде процессора аннотаций? Обычно используется объект filer внутри блока кода, например

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

(в методе метода). Это гарантирует, что обработчик аннотации не будет в последнем раунде (последний раунд всегда является тем, у которого есть пустой набор аннотаций).

2) Если вы действительно не можете избежать написания сгенерированных файлов в последнем раунде, и эти файлы являются исходными файлами, обманите обработчик аннотации и используйте метод "createResource" объекта filer (возьмите "SOURCE_OUTPUT" в качестве местоположения).

Ответ 3

Я ткнул вокруг параметров компилятора java 7, и я нашел это:

-implicit: {класс, ни один}  Управляет генерацией файлов классов для неявно загруженных исходных файлов. Чтобы автоматически генерировать файлы классов, используйте -implicit: class. Чтобы подавить генерации файлов классов, используйте -implicit: none. Если этот параметр не указан, по умолчанию используется автоматическое создание файлов классов. В этом случае компилятор выдает предупреждение, если такие файлы классов генерируются при выполнении обработки аннотаций. Предупреждение не будет выдано, если эта опция задана явно. См. Поиск типов.

Источник

Можете ли вы попробовать и неявно объявить файл класса.