Плагин уха Maven - "удвоенный" артефакт, когда не используется чистый

При создании уха через плагин уха Maven я испытал, что применение package без clean может привести к несогласованным результатам: если я изменю версию зависимости, зависимость теперь появляется дважды в ухе, в старой и новой. Если я создаю ухо без номеров версий в именах jar, я получаю только одну банку, но старые версии не заменяются должным образом.

Я посмотрел исходный код

http://svn.apache.org/viewvc/maven/plugins/tags/maven-ear-plugin-2.10.1/src/main/java/org/apache/maven/plugin/ear/EarMojo.java?view=markup

Особенно интересны строки из 436: проверяется, следует ли обновлять файлы в целевом объекте, но, по-видимому, проверяет только абсолютный путь и дату последнего изменения.

Подводя итог: Правильно ли мне, что изменение зависимостей (или их версий) всегда требует вызова clean перед сборкой? Или есть какой-то интеллект в package, который я пропустил?

Ответы

Ответ 1

Да... большую часть времени вы должны вызывать clean при изменении зависимостей или любой другой конфигурации сборки, в противном случае предыдущие элементы сборки могут столкнуться с новой сборкой (как кажется, ваша случай здесь). Вообще говоря, чтобы предыдущие элементы сборки не сталкивались с новой сборкой, вы должны называть clean before-hand - изменения конфигурации или нет.

Но есть исключения:, если вы точно знаете, что предыдущие элементы сборки не повлияют на вашу новую сборку, вы можете пропустить clean. Однако большую часть времени вы не можете знать или пропустить clean просто невозможно, не вызывая таких столкновений. Ниже я подробно объясню.


Когда вы создаете свой проект с Maven, он будет генерировать файлы и другие элементы в папке ${project.build.directory} (target по умолчанию). Эти элементы затем используются для создания вашего артефакта (EAR в вашем случае) во время фазы package.

Без вызова clean после сборки все элементы под target все равно будут присутствовать во время следующей сборки и могут повлиять на нее. Как могут плагины Maven различать и знать, какие элементы из старых сборников или новые? Масштабирование файлов, очевидно, недостаточно, и, если не использовать какой-то механизм obscur для определения того, какие файлы из сборника, это трудно сделать.

Если я изменяю версию зависимости, теперь появляется зависимость дважды в ухе, в старой и новой версиях.

Вероятно, из-за того, что ваши зависимостей копии сборки в target и ваш упаковочный плагин будут включать весь каталог в сгенерированный артефакт (в вашем случае - EAR). Например, если вы дважды запускаете свою сборку с другой версией:

  • Первая сборка: mydep-1.0.jar создается в target/classes/mydep, и ваш плагин включает в себя все файлы из target/classes/mydep в EAR. Все в порядке.
  • Создается вторая сборка: mydep-2.0.jar, но mydep-1.0.jar все еще находится в target/classes/mydep. Полный каталог target/classes/mydep включен, а обе версии - в EAR.

Если я создаю ухо без номеров версий в именах баннеров, я получаю только одна банка, но старые версии не заменены должным образом.

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

  • В первом случае существовал mydep-0.1.jar и был создан новый mydep-0.2.jar, но оба были включены в ваш EAR
  • Теперь без версии у вас есть mydep.jar, которая не переопределяется самой последней версией, потому что "она уже существует", поэтому "старый" файл остается на месте и входит в EAR.

Заключение: плагины Maven не могут дифференцироваться со 100% уверенностью, если элемент принадлежит предыдущей сборке или новой. Когда вы обновляете конфигурацию сборки, вы всегда должны вызывать clean, чтобы убедиться, что столкновение старых и новых элементов сборки не будет. Даже без изменений конфигурации сборки может потребоваться вызвать clean - но это другое дело.

Я бы рекомендовал всегда вызывать clean при запуске сборки, если не произойдет столкновение, и оно обеспечивает реальную ценность, такую ​​как увеличение времени, потому что перестройка всего проекта слишком велика или другие причины, оправдывающие его.

EDIT: согласно запросу @JF Meier для источников, Руководство для запуска Maven предоставляет советы в соответствии с целями clean и связанной с ними непоследовательностью риски:

Несогласованный вывод

Большинство плагинов оптимизированы, чтобы знать, должны ли они выполнять свою задачу. В некоторых случаях выход может быть загрязнен из предыдущей сборки, а конечный результат - это не то, что вы ожидали. В таких редких ситуациях вы можете вызовите фазу clean, что означает: удалить выходной каталог. Вы может также называть его mvn clean verify, что означает: сначала очистить вывода, затем создайте проект и проверьте результат.

Ответ 3

Архив уха связывает все зависимостей проекта с zip (по структуре, заданной в формате уха). Архив построен в два этапа: сначала модуль ear-maven-plugin собирает зависимости проекта, а затем создает архив. Эти зависимости копируются в файл ${project.build.directory}.

Итак, чистый должен всегда использоваться с этим подключаемым модулем, чтобы предотвратить любые несоответствия, вызванные добавлением зависимостей в каталог, в котором предыдущее выполнение могло бы скопировать другой снимок зависимостей. Если чистая фаза пропущена, каталог ${project.build.directory} не будет усечен, что, скорее всего, вызовет несогласованности в построенном пакете.