Размер шрифта:
Создание своих архетипов и каталогов в Maven
Play

Создание своих архетипов и каталогов в Maven

Уже довольно продолжительное время (около года набежит) активно пользуюсь системой сборки Apache Maven и вполне ею доволен. Несмотря на свои очевидные и не очень недостатки, неоспоримым преимуществом является автоматическое управление зависимостями, хорошая структурированность проектов и отсутствие скриптов сборки как таковых, а следовательно проблем с ними.

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

Поиск плагинов и их настройка — это тоже мучительные круги ада, но по сравнению с xml-программированием на ant'e это еще ничего.

Однако при правильном подходе и набитом скилле, мавен практически не ощущается в работе, что мне очень нравится.

Собственно, в этой статье речь пойдет не о муках, а о архетипах, их каталогах и создании собственных архетипов и каталогов. С помощью этих нехитрых концепций можно ощутимо упростить себе жизнь при создании нового проекта.

Создаем локальный каталог

Архетип в мавене — это шаблон нового проекта, со структурой и заготовками исходных и конфигурационных файлов.

Любой, кто хотя бы раз создавал проект на мавене, сталкивался с архетипами. Например, типичный метод создания проекта, который витает в интернете:

Вопрос, откуда взять нужные параметры, всегда меня волновал, обычно я вежливо спрашиваю у Гугла и он мне обычно отвечает :)

Если мы например, захотим создать простоe приложение, то мы используем архетип под названием maven-archetype-quickstart, например вот так:

Есть более удобный способ создания проекта, с помощью цели archetype:generate. При вызове, в интерактивном режиме будет предложено ввести параметры нового проекта.

Но тут возникает проблема. Мавен предлагает выбрать тип нового проекта из списка готовых шаблонов, а список состоит ни много ни мало из более чем 300 вариантов. Найти там нужный шаблон — задача довольно нетривиальная, обычно я сбрасываю вывод в файл и потом грепом ищу то что нужно.

Погуглив немного, я нашел для себя решение этой проблемы, не совсем как по мне окончательное, но вполне себе с намеком на элегантность. Архетипы можно обьединять в каталоги! Но как это может помочь?

Каталог определяется URL'ом, где он расположен, кроме того в мавене есть три предопределенных каталога, или если хотите, алиаса: internal, remote и local.

У цели archetype:generate есть параметр archetypeCatalog, с помощью которого можно указать список каталогов, где нужно искать возможные архетипы. По умолчанию, значение параметра 'remote,local'. Но если убрать оттуда remote, то получим почти то, что нужно.

Например, вот так:

Подсмотреть структуру файла можно из каталога remote. Например, чтобы получить список выше, файл должен иметь вид

Немного поколдовав с конфигурацией мавена, можно сделать такую ситуацию постоянной, нужно создать профиль, в котором выставить значение переменной archetypeCatalog. Для этого в ваш файл settings.xml нужно добавить

Усе! Теперь, при вызове, цель archetype:generate вместо тонн мусора, будет выводить вам то, что скажете.

К слову у плагина archetype есть любопытная цель crawl, которая сканирует ваш локальный репозиторий на предмет наличия архетипов и генерирует из всех найденных каталог. К сожалению, документация немного врет и по умолчанию файл генерируется совсем не там где ожидает увидеть его мавен. Готовить нужно так:

Вопреки официальной документации параметр называется не catalogFile, а catalog.

Создаем свой архетип

Вторая проблема, которую мы рассмотрим — это создание собственного архетипа. Зачем это нужно? Нужно это по той простой причине, что при всем кажущемся обилии архетипов, среди них не оказалось подходящего для простой веб-разработки. Есть несколько близких по духу, например тот же maven-archetype-webapp, но дескрипторы в нем устаревшие, нету log4j и нормального темплейта jsp. В итогое после создания пустого проекта, нужно перейти в режим работы напильником, и с помощью гугла переделывать все как надо. В конце концов на десятый раз мне это надоело, и я решил создать свой собственный архетип, самый лучший и самый правильный. Более конкретно, создадим заготовку для простенького приложения на spring-mvc c использованием Servlet 2.5/JSP 2.1/JSTL 1.2 c готовым к работе логированием.

Внимание, в следующем абзаце возможно зависание от количества упоминаний слова архетип.

Для начала нужно создать проект для нашего архетипа, используя архетип maven-archetype-archetype, например с помощью того же archetype: сreate.

Чтобы не мучится в консоли, пересядем в эклипс, хотя конечно же все, что написано ниже, можно сделать и с помощью vim'а или еще чегото такого.

После чего делаем импорт и смотрим на структуру более детально.

Проект состоит из одной папки resources, в которой содержися две подпапки: archetype-resources и META-INF. В первой храниться костяк будущих выдающихся проектов, которые еще будут созданы поколениями програмистов после нашей смерти, во второй хранится файлик META-INF/maven/archetype.xml. Это дескриптор архетипа. В нем будет хранится описание того, что входит в архетип.

Дополним костяк, всем чем нужно: добавим туда простенькую jsp страничку, более-менее сносный web.xml, простенький контроллер и конфиг log4j.properties. Все это вы найдете в архиве, который можно скачать. Из интересных моментов, на которые стоит обратить внимание, это замены, которые делает мавен при создании проекта. В архетипе реализован механизм темплейтов на основе Velocity, который практически не документирован, если ктото уверен в обратном, поделитесь, буду благодарен.

В частности в контроллере через темплейты реализована подстановка имени пакета.

Тот же самый ход использован в конфигурации Spring MVC и при генерации целевого pom.xml. Пока что список известных мне переменных довольно скуден: $groupId, $artifactId, $version и $package. Думаю, всем понятно, что каждый значит, все это указывается при создании проекта из архетипа.

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

Когда процесс подготовки шаблонов завершен, нужно подготовить файл-дескриптор архетипа, тот самый archetype.xml.

Тэг должен совпадать с artifactId нашего архетипа. Тэги <sources> и <resources> прдназначены для темплейтов разных частей архетипа. В частности ресурсы из папки webapp нужно указывать в тэге <resources>. Есть еще несколько допустимых секций. Ниже перечислены допустимые секции и папки, куда уйдут указанные в них шаблоны.

<sources> src/main/java <resources> src/main/resources <testSources> src/test/java <testResources> src/test/resources <siteResources> src/site

После того как все готово, можно установить наш архетип в репозиторий с помощью

и теперь он готов к использованию.

Наш маленький проект готов к запуску

После чего по ссылке http://localhost:8080/baremvcapp можно узреть сие творение.

Теперь архетип, можно сказать приготовлен, добавим его в локальный каталог руками или с помощью цели archetype:crawl.

Теперь при вызове archetype:generate в списке должна появиться строчка

с чем я нас и поздравляю.

В заключение осталось добавить, что описанный выше способ устарел (увы), и помечен как deprecated, но все еще работает, а про right way документации как то кот наплакал. Все что мне пока известно, это что дескриптор изменили, теперь он называется archetype-metadata.xml и имеет более мощный синтаксис. Надеюсь хватит еще на десяток лет вперед статьи писать.

Использованные ресурсы
  1. Guide to Creating Archetypes — http://maven.apache.org/plugins/maven-archetype-plugin-1.0-alpha-7/examples/archetype.html
  2. Maven Archetype Plugin — http://maven.apache.org/archetype/maven-archetype-plugin/
  3. Maven – размышления после двух лет использования — http://habrahabr.ru/blogs/personal/102181/

UPD: Есть еще цель archetype:create-from-project, которая сгенерирует шаблон из вашего проекта. Шаблон сгенерируется в папку target/generated-sources/archetype. То есть фактически из любого вашего проекта можно сгенерировать архетип и потом использовать его в качестве отправной точки. Спасибо 1nd1go

📎📎📎📎📎📎📎📎📎📎