Плагин компилятора 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] ------------------------------------------------------------------------
Ответы
Ответ 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.