Компилятор Maven для компиляции всех файлов, а не модифицированных
Даже если я изменяю только один из своих классов, Maven всегда перекомпилирует их все. Я использую эту конфигурацию плагина:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<staleMillis>1</slateMillis>
<useIncrementalCompilation>true</useIncrementalCompilation>
</configuration>
</plugin>
</plugins>
Это происходит с mvn compile
, mvn package
и mvn install
.
Конечно, это не проблема, если у вас есть 10-15 файлов. Однако у меня есть более тысячи исходных файлов, и это занимает много времени.
Делает плагин компилятора Мэйвен имеет некоторые скрытые настройки, чтобы перекомпилировать только измененные файлы? Есть ли обходные пути?
3 ответа:
Https://issues.apache.org/jira/browse/MCOMPILER-209
Используйте его с болгарской нотацией (да нет)
<useIncrementalCompilation>false</useIncrementalCompilation>
означает истинный и наоборот
Резюме
В то время как Вы можете сказать Maven "перекомпилировать только измененные файлы", это приведет к неправильным результатам. Поведение по умолчанию-это не ошибка, а преднамеренное проектное решение.
Что
Документация по этой теме, мягко говоря, не оптимальна. Вот что действительно происходит (на основе AbstractCompilerMojo source fromuseIncrementalCompilation
на самом деле делаетmaven-compiler-plugin
3.3):
useIncrementalCompilation
установить вfalse
(Нет рекомендуется )
- при этом будут компилироваться только исходные файлы, которые являются более новыми, чем соответствующие им файлы классов, т. е. которые были изменены с момента последнего процесса компиляции. Как отмечает @Ivan в комментарии к другому ответу, это не будет перекомпилировать другие классы, которые используют измененный класс, потенциально оставляя их со ссылками на методы, которые больше не существуют, что приводит к ошибкам во время выполнения.
useIncrementalCompilation
установить вtrue
(default )
- для обработки проблема, описанная выше, в этом режиме плагин компилятора будет определять, является ли
- любые JAR-файлы, от которых зависит текущий модуль, были изменены в текущем запуске сборки, или
- любой исходный файл был добавлен, удален или изменен с момента последней компиляции.
- Если это так, то плагин компилятора намеренно перекомпилирует все исходники, печатая
Changes detected - recompiling the module!
Таким образом, в общем,
useIncrementalCompilation
всегда следует оставлять по умолчаниюtrue
.
Почему он не делает что-то другое
Понятно, что можно спросить: почему плагин не определяет, какие классы затронуты изменениями, и перекомпилирует только эти классы? Так вот, в комментариик MCOMPILER-205 разработчик Maven Роберт Шолте пишет:Причина в том, что компилятор java по умолчанию довольно быстр, вероятно, намного быстрее, чем анализ каждого файла, что с ним делать.
Таким образом, решение было просто перекомпилируйте все. Однако, как Роберт также пишет в этом комментарии, это, вероятно, не нужно, если проект использует компилятор Eclipse, который делает этот анализ. Но для сегодняшних пользователей Maven это спорный вопрос, поскольку
maven-compiler-plugin
еще не меняет свое поведение, основанное на выборе компилятора.
Вероятно, плохие новости: см. bug MCOMPILER-205.