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

Плагин компилятора Maven всегда обнаруживает набор источников как "устаревший",

FIXED: это известная ошибка в maven-compiler-plugin 3.1

Я преобразовываю построенный на основе ant проект проекта с более чем 1000 Java-ресурсами для maven. Пока все хорошо, но каждый раз при запуске mvn compile он перекомпилирует все (вместо повторного использования старых классов)

Используя mvn -X compile сообщает, что

[DEBUG] Stale source detected: /project_path/src/main/java/package_path/AFile1.java
[DEBUG] Stale source detected: /project_path/src/main/java/package_path/AFile2.java
...

( только для файлов в определенном пакете, который, возможно, не привязан к остальной части кода, а не к моим источникам, я просто пытаюсь изменить порядок сборки)

Компиляция не прерывается, а классы с обновленными метками времени генерируются в

/project_path/target/classes/package_path/AFile1.class
/project_path/target/classes/package_path/AFile2.class
...

Однако при просмотре временных меток java файлы не менялись со вчерашнего дня, а файлы классов являются текущими. Почему эти источники считаются устаревшими? Как я могу отладить эту проблему?

Это перетащить, чтобы перекомпилировать файлы 1k +, даже если никаких изменений не произошло...


Пример вывода:

$ mvn clean compile
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building MyProject 1.9.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for net.sourceforge:jffmpeg:jar:1.1.0 is missing, no dependency information available
[INFO] 
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ my-project ---
[INFO] Deleting /project_path/target
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ my-project ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /project_path/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ my-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1162 source files to project_path/target/classes
....
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.215s
[INFO] Finished at: Tue Jul 30 12:42:25 CEST 2013
[INFO] Final Memory: 25M/429M
[INFO] ------------------------------------------------------------------------



$ mvn compile
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building MyProject 1.9.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for net.sourceforge:jffmpeg:jar:1.1.0 is missing, no dependency information available
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ my-project ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /project_path/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ my-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1162 source files to /project_path/target/classes
... 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.140s
[INFO] Finished at: Tue Jul 30 12:42:44 CEST 2013
[INFO] Final Memory: 22M/379M
[INFO] ------------------------------------------------------------------------
4b9b3361

Ответ 1

Это известная проблема в maven-compiler-plugin 3.1. Он отслеживается в https://issues.apache.org/jira/browse/MCOMPILER-209 (нарушается флаг useIncrementalCompilation).

Проблема не связана с другой ошибкой 3.1, https://issues.apache.org/jira/browse/MCOMPILER-205 (где файлы, которые не производят .class-выходы, всегда помечены как "устаревшие" ).

После тестирования далее, вернувшись к 3.0, на самом деле не исправить проблему (она работает только до следующего mvn clean compile. Однако, как предлагает Майкл Лемке в комментариях, маркировка useIncrementalCompilation до false является работоспособной заменой; теперь только нарушающий пакет перекомпилируется каждый раз (вместо всего кода).

Ответ 2

Maven может отображать сообщение типа:

[INFO] Обнаружены изменения - перекомпиляция модуля!

Поскольку у вас есть пустой java файл (или все закомментированные) в проекте, который никогда не компилируется в файл класса.

Вы можете определить причину, по которой maven восстанавливается, запустив maven с -X. Посмотрите на приведенное выше сообщение.

Ответ 3

Моя ситуация была немного иной, поэтому я просто добавляю это, если у кого-то другая проблема. Мой проект не имеет сгенерированных классов и не package-info.java; только .java файлов в src/main/java.

TL;DR

Обновить до maven-compiler-plugin 3.1 или использовать maven-compiler-plugin 3.0 и не устанавливать <overwrite>true</overwrite> в maven-resources-plugin.


Длинная версия

При нулевом изменении дерева src Maven всегда показывал вывод, например:

$ mvn -o compile

[INFO] --- maven-compiler-plugin:3.0:compile (default-compile) @ my-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 134 source files to /home/me/my/project/target/classes

Я думал, что это была конфигурация maven-resources-plugin в родительском POM, который использует мой проект.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <overwrite>true</overwrite>
    </configuration>
</plugin>

Удаление этого плагина из родительского POM или переопределение в моем проекте с помощью <overwrite>false</overwrite> устраняет проблему с добавочной сборкой.

Я задавался вопросом, почему мне пришлось делать две сборки после установки <overwrite>false</overwrite> для Maven для повторной инкрементной сборки, поэтому исследовали дальше. Это просто потому, что первый компилятор генерирует файл (называемый inputFiles.lst), который используется для определения файлов, которые были изменены, поэтому в следующем компиле он может использовать этот файл для обнаружения изменений. Это подтверждается комментарием на MCOMPILER-187.

Я понял, что использовал maven-compiler-plugin 3.0 и мог просто обновиться до

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
</plugin>

который также устранил проблему. 3.1 использует maven-shared-incremental 1.1 (вместо 1.0, который использует maven-compiler-plugin 3.0. Обратите внимание, что MCOMPILER-187 и MSHARED-264 являются 2 ошибками, охватывающими изменение.

Итак, вернемся к maven-compiler-plugin 3.0, я заметил, что target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst не сгенерирован с набором <overwrite>true</overwrite>. Таким образом, это может быть причиной того, что проект не может иметь инкрементные сборки при использовании maven-compiler-plugin 3.0.

Очевидно, что перезапись ресурсов каждый компилятор обычно не требуется, но главная проблема заключается в том, что inputFiles.lst никогда не генерируется, поэтому Maven никогда не сможет создать инкрементную сборку. Поэтому проверьте существование inputFiles.lst, поскольку, возможно, другой плагин каким-то образом не вызвал его.

Ответ 4

Я не понимаю, почему, но решение из ответа tucuxi не работает в моем случае. В моем проекте есть тысячи файлов, созданных специальным инструментом, и его перекомпиляция может тратить очень много времени.

Я пробовал следующую конфигурацию плагина (с уровнем Java 1.5):

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>1.5</source>
        <target>1.5</target>
        <useIncrementalCompilation>true</useIncrementalCompilation>
    </configuration>
</plugin>

Во втором запуске не обнаружены устаревшие файлы, но плагин снова скомпилировал весь проект. По-видимому, инкрементная компиляция фактически отключена по умолчанию и все еще не работает, даже если указан параметр useIncrementalCompilation = true.

После некоторого googling я просто изменил значение параметра useIncrementalCompilation с "true" на "yes", и это делает трюк для меня.

@see также fooobar.com/questions/156032/...

Ответ 5

Если вы уверены, что никаких изменений не было, вы можете передать -Dmaven.main.skip. У меня есть проект, в котором я делаю это после запуска Proguard, так как это единственный способ повторно использовать Proguarded jar для тестов. (Примечание: я запускаю те же модульные тесты перед Proguard, что и после, чтобы убедиться, что Proguard ничего не сломал. Чтобы максимально приблизить это к стандартному рабочему процессу Maven, я делаю предварительный прогон в Surefire и после него. Proguard работает в Failsafe.)

Ответ 6

Другой способ, которым это может произойти, - если ваше исходное местоположение файла и имя пакета не совпадают.

например, если у вас есть исходный файл в src/main/java/com/example/MyClass.java но класс объявлен в несовпадающем пакете com.example.util:

package com.example.util;

class MyClass { ... }

Скомпилированный файл класса будет в конечном итоге в target/classes/com/example/util/MyClass.class и это будет путать проверку "устаревшего файла".

Ответ 7

Я откатил плагин компилятора maven до версии 2.3.2, и он без проблем компилирует только модифицированные классы с java 8.

Ответ 8

Столкнулся с такой же проблемой. -X Maven mvn compile с -X показала, что проблема вызвана файлом package-info.java.

[DEBUG] Обнаружен устаревший источник:.../package-info.java

Проблема в том, что для package-info.java не создан файл .class.

Решение было найдено в этом PR: https://github.com/apache/flink/pull/5644/files со ссылкой на MCOMPILER-205

<compilerArgs>
    <arg>-Xpkginfo:always</arg>
</compilerArgs>

что значит:

Всегда генерируйте package-info.class для каждого файла package-info.java.