Лучшая практика Maven для создания нескольких банок с различными / отфильтрованными классами? - PullRequest
32 голосов
/ 11 марта 2010

Я разработал библиотеку утилит Java (аналогично Apache Commons), которую я использую в различных проектах. В дополнение к толстым клиентам, я также использую его для мобильных клиентов (PDA с профилем J9 Foundation). Со временем библиотека, которая начиналась как один проект, распространилась на несколько пакетов. В результате я получаю много функциональности, которая на самом деле не нужна во всех проектах.

Поскольку эта библиотека также используется в некоторых проектах для мобильных устройств / PDA, мне нужен способ собрать только используемые классы и создать фактические специализированные jar-файлы.

В настоящее время в проектах, использующих эту библиотеку, у меня есть задачи Ant jar, которые генерируют (из служебного проекта) специализированные файлы jar (например: my-util-1.0-pda.jar, my-util-1.0-rcp .jar) с использованием функций включения / исключения jar. Это главным образом необходимо из-за ограничений размера генерируемого файла JAR для мобильных проектов.

Миграция сейчас в Maven Мне просто интересно, есть ли лучшие практики для достижения чего-то подобного. Я рассматриваю следующие сценарии:

[1] - в дополнение к основному артефакту jar ( my-lib-1.0.jar ), также генерирующему внутри my-lib , проектируют отдельный / специализированные артефакты с использованием классификаторов (например: my-lib-1.0-pda.jar ) с использованием фильтрации Maven Jar Plugin или Maven Assembly Plugin / include. Мне не очень удобен такой подход, так как он загрязняет библиотеку требованиями потребителей (фильтрами).

[2] - Создайте дополнительные проекты Maven для всех специализированных клиентов / проектов, которые "обернут" "my-lib" и сгенерируют отфильтрованные артефакты jar (например: my- lib-wrapper-pda-1.0 ... и т. д.). В результате эти проекты-оболочки будут включать фильтрацию (для создания отфильтрованного артефакта) и будут зависеть только от проекта «my-lib», а клиентские проекты будут зависеть от my-lib-wrapper-xxx-1.0 вместо my-lib-1.0 . Такой подход может показаться проблематичным, поскольку даже это позволит сохранить проект my-lib без каких-либо дополнительных классификаторов и артефактов, в основном удвоит количество проектов, поскольку для каждого клиентского проекта у меня будет одна библиотека, просто для сбора необходимой классы из библиотеки "my-util" (проекту "my-pda-app" потребуется проект / зависимость "my-lib-wrapper-for-my-pda-app").

[3] - В каждом клиентском проекте, использующем библиотеку (например: my-pda-app ), добавить несколько специализированных плагинов Maven для обрезки (при генерации конечного артефакта) / package) классы, которые не требуются (например: maven-assembly-plugin, maven-jar-plugin, proguard-maven-plugin).

Какова наилучшая практика для решения такого рода проблем "Maven путь"?

1 Ответ

24 голосов
/ 11 марта 2010

Общее правило Maven - «один первичный артефакт на POM» ради модульности, и причины, по которым не следует нарушать это соглашение (в общем), очень хорошо объяснены в Как создать два JAR-файла из одногоПроект (... и почему вы не должны) сообщение в блоге.Однако существуют оправданные исключения (например, проект EJB, создающий EJB JAR и клиентский EJB JAR только с интерфейсами).Сказав, что:

В упомянутом сообщении в блоге (также отметьте Использование Maven, когда вы не можете использовать условные обозначения ) объясняется, как можно реализовать Вариант 1 с использованием отдельных профилей или плагина JAR .Если вы решили реализовать это решение, имейте в виду, что это должно быть исключением и что это может усложнить управление зависимостями (и, как вы упомянули, загрязнять проект "логикой фильтрации клиентов").На всякий случай, я бы использовал здесь несколько плагинов JAR.

Вариант 2 не сильно отличается от Вариант 1 IMO (за исключением того, что он разделяет вещи): в основном, наличие N других проектов упаковки / фильтрации очень похоже наимея N правил фильтрации в одном проекте.И если фильтрация имеет смысл, я предпочитаю Вариант 1.

Мне совсем не нравится Вариант 3 , потому что я думаю, что клиент библиотеки не должен отвечать за "обрезать "ненужные вещи.Во-первых, клиентский проект не обязательно обладает необходимыми знаниями (что нужно обрезать), а во-вторых, это может создать большой беспорядок с другими плагинами.

НО , если жирные клиенты не с использованием всего my-lib (как серверный код потребовал бы всего EJB JAR), тогда фильтрация не является правильным "maven способом" для решения вашей ситуации.Правильный путь был бы Вариант 4 : поместить все общее в проект (создание my-lib-core-1.0.jar ) и конкретные части в конкретных проектах (которые будут производить * 1035)* my-lib-pda-1.0.jar и т. д.).Клиенты будут зависеть от основных и специализированных артефактов.

...