Pom файлы что это
Вместо вывода
Сегодня мы быстро прошлись по тому, что такое Maven, что там есть, какие основные команды там есть. Я постарался донести это просто и с примерами. Все исходники примера лежат в организации JavaRush Community на GitHub в проекте maven-demo. Все вопросы пишите в комментариях. Традиционно предлагаю подписаться на мой аккаунт на гитхабе, чтобы не пропустить новый код для нашего проекта JRTB. Еще раз повторю, он не мертв. Он был просто в стазисе))
После публикации топика о Maven в комментариях возникли вопросы о том, как начать с ним работать, с чего начать, как составлять файлы pom.xml, откуда брать плагины и т.п. Данный топик будет своего рода getting started или f.a.q.
Как в любой системе, в Maven, есть свой набор терминов и понятий.
Вся структура проекта описывается в файле pom.xml (POM – Project Object Model), который должен находиться в корневой папке проекта. Ключевым понятием Maven является артефакт — это, по сути, любая библиотека, хранящаяся в репозитории. Это может быть какая-то зависимость или плагин.
Зависимости — это те библиотеки, которые непосредственно используются в вашем проекте для компиляции кода или его тестирования.
Плагины же используются самим Maven'ом при сборке проекта или для каких-то других целей (деплоймент, создание файлов проекта для Eclipse и др.).
В самом начале работы с Maven, пользователь непременно столкнется с таким понятием как архетип. Архетип — это некая стандартная компоновка файлов и каталогов в проектах различного рода (веб, swing-проекты и прочие). Другими словами, Maven знает, как обычно строятся проекты и в соответствии с архетипом создает структуру каталогов.
Как правило, название артефакта состоит из названия группы, собственного названия и версии. К примеру Spring будет иметь вот такое название в среде Maven: org.springframework.spring:2.5.5. Последний домен означает всегда artifactId, все, что перед ним – groupId – хорошо это запомните!
На жизненном цикле останавливаться не буду, так как он хорошо описан в вышеобозначенной статье. А теперь перейдем к практике.
Последнюю версию всегда можно скачать на странице загрузки на официальном сайте. Просто распаковываем архив в любую директорию. Далее необходимо создать переменную в Path, в которой необходимо указать путь к Maven. Заходим в Win + Pause – Дополнительно – Переменные среды – в верхнем окошке нажимаем Создать, вводим имя M2_HOME и значение допустим “C:\apache-maven-2.2.1”. Далее там же создаем еще одну переменную M2 со значением %M2_HOME%\bin. Так же убеждаемся, что есть переменная JAVA_HOME с путем к JDK. Ее значение должно быть примерно таким «c:\Program Files\Java\jdk1.6.0_10\». И наконец в том же окошке создаем/модифицируем переменную Path, в нее необходимо просто написать %M2%, чтобы наша папочка с исполняемым файлом Maven была видна из командной строки. Теперь необходимо проверить работоспособность нашей установки. Для этого заходим в командную строку и вводим команду
Должна появиться информация о версиях Maven, jre и операционной системе, что-то вроде:
Maven создаст вам локальный репозиторий в вашей личной папке, например в каталоге C:\Documents and Settings\username\.m2\repository
Все, Maven готов к работе, можно приступать к созданию приложения.
На сайте Maven перечислены наиболее популярные архетипы для приложений, но вы можете легко создать свой или найти более специфичный например здесь.
Итак, допустим нас интересует веб-приложение – находим подходящий архетип, называется он maven-archetype-webapp. В командной строке, в необходимом каталоге выполняем команду Maven:
Теперь мы можем лицезреть довольно наглядную структуру каталогов с говорящими названиями java – здесь будут ваши классы, webapp – здесь размещаются странички веб-приложения, resources – различного рода ресурсы в classpath (файлы конфигурации, например), test – юнит-тесты, соответственно и т.п.
Здесь все просто – выполняем команду
в корневом каталоге приложения, там, где находится файл pom.xml. Первая команда скомпилирует ваш проект и поместит его в папку target, а вторая еще и положит его к вам в локальный репозиторий.
Есть полезная функция, наподобие конвеера, то есть можно написать
и Maven сначала очистит папку target проекта, потом соберет его и положит в репозиторий.
Минимальный набор действий для работы Maven мы изучили, теперь переходим к кастомизации и добавлению зависимостей проекта.
Как правило, большинство популярных библиотек находятся в центральном репозитории, поэтому их можно прописывать сразу в раздел dependencies вашего pom-файла. Например чтобы подключить Spring Framework необходимо определить следующую зависимость:
Версию хотя и можно не указывать и тогда Maven возьмет последний вариант, но я вам лично советую это делать, потому как у нас неоднократно бывали случаи, что проект просто в один момент переставал собираться или начинал падать в совершенно неожиданных и хорошо оттестированных местах, хотя вроде бы никто ничего не менял.
Специфические вещи обычно не находятся в центральном репозитории и тогда вам придется указать репозиторий производителя вручную. Для примера добавим зависимость JSF-фреймворка ajax-компонентов JBoss RichFaces.
С зависимостями все просто:
А вот репозиторий JBoss теперь необходимо прописать ручками либо в файле settings.xml, который лежит в корне вашего локального репозитория, либо в самом файле pom.xml, в зависимости от того, нужен ли данный репозиторий во всех проектах, либо в каком-то одном конкретном, соответственно:
Последний параметр чаще всего имеет значение jar.
Так как плагины являются такими же артефактами, как и зависимости, то они описываются практически так же. Вместо раздела dependencies – plugins, dependency – plugin, repositories – pluginRepositories, repository – pluginRepository.
Плагинами Maven делает все, даже непосредственно то, для чего он затевался – сборку проекта, только этот плагин необязательно указывать в свойствах проекта, если вы не хотите добавить какие-то фичи.
Посмотрим как настроить плагин для создания проекта для Eclipse с использованием WTP ver. 2.0. В раздел plugins нашего pom.xml прописываем следующий плагин:
Теперь идем опять таки в командную строку и выполняем команду
Ждем пока Maven найдет все библиотеки в репозитории или скачает их и вуаля – теперь наш Maven-проект можно открыть как проект eclipse. При этом библиотеки никуда не копируются как при классическом подходе, а остаются в репозитории и Eclipse делает на них ссылку через свои переменные.
Единого списка всех плагинов естественно не существует, на официальном сайте только есть поддерживаемые плагины непосредственно разработчиками Maven. Однако хотелось бы отметить, что названия плагинов довольно прямолинейны и сделав поиск по ключевым словам «maven tomcat plugin» вы скорее всего обнаружите первой ссылкой плагин для деплоймента проекта в Tomcat.
К сожалению сам не имею большого опыта настройки репозитория, но могу посоветовать как наиболее простой и распространенный Nexus. За дополнительной информацией следует обратиться на сайт данного проекта.
Однако нельзя оставить без внимания и достойных конкурентов в лице Artifactory и Archiva.
Очень надеюсь, что цель данной статьи достигнута – минимальных знаний по Maven должно хватить на работу с не очень большими проектами. Для более серьезных целей очень советую детально изучить maven-compiler-plugin и maven-resource-plugin – они напрямую отвечают за конечную компоновку проекта. Я считаю, что самым главным моментом в обучении Maven является понимание идеологии – Maven описывает конечную структуру проекта, а не пути к ее достижению, в отличие от Ant.
Полезные ссылки
Официальная страница Maven
Документация
Центральный репозиторий
Репозиторий iBiblio
Поиск артефактов по названию
Неплохой форум по Maven
Maven: The Definitive Guide — хорошая книга по Maven
Думаю, для большинства хабражителей не будет откровением, что среди крупных софтварных разработок нередко встречаются технологии и языки значительно отстающие от передовых. К сожалению, это неизбежность, т. к. невозможно в какой-то момент взять и переписать несколько миллионов строк кода на другой язык или с применением более современного фреймворка.
Но в какой то момент отставание становится настолько существенным, что продукт перестает быть конкурентоспособен и постепенно исчезает с рынка. Именно такую ситуацию постепенного затухания мне и довелось наблюдать.
Здесь я хочу рассказать о том, как в конкретном случае я постарался оттянуть неизбежное и оживить разработку применив для этого сборщик проектов Maven.
Главным достоинством разработанной мною системы, пожалуй, можно назвать то, что небольшим количеством трудозатрат, можно при помощи Maven научить проект, реализованный на любом языке, собираться из отдельных Пакетов, соблюдающих свою версионность и автоматически обновляющихся при сборке проекта. Все что для этого нужно, это утилита командной строки, которая может скомпилировать исходник, а в случае скриптовых языков была бы полезна утилита валидации.
Итак дано:
— Система, «ядро» которой состоит из набора dll и отдается прикладным разработчикам без исходников.
— Прикладной язык программирования, который подобен Паскалю, но кроме стандартных возможностей Паскаля(из которых доступно далеко не все) позволяет использовать объекты, реализованные в dll «ядра». Данный прикладной язык компилируется в подобие байт кода и исполняется отдельной dll «ядра».
Таким образом, основная разработка ведется на описанном выше волшебном прикладном языке, все прелести которого, пожалуй, могли бы ужаснуть уважаемое сообщество, а «ядро» периодически(новая версия раз в пару месяцев) поставляется из головного офиса и не подлежит модификации.
Очень вероятно, что разработка и поддержание собственного языка программирования похожего на Паскаль и сделанного на базе Delphi возможно была плохой идеей, но 15-17 лет назад, когда все это начиналось, об этом никто не думал. Преследовались другие цели, которые в общем-то с успехом были достигнуты.
Сама система представляет из себя продаваемый заказчику продукт с сервером, клиентом и тонким клиентом. Естественно, большинство клиентов не удовлетворяются стандартным функционалом системы, поэтому существует несколько отделов прикладной разработки, “допиливающих”систему под их нужды. Каждым проектом занимается обособленная группа программистов. Взаимодействие и обмен опытом между группами катастрофически малы. Таким образом, каждая группа получает свой шанс переизобрести велосипед и наступить по десятому разу на одни и те же грабли.
Проведя анализ, стало понятно, что такое отсутствие взаимодействия отделов объясняется прежде всего нехваткой механизмов использования общего кода. Иными словами, если все-таки, происходил обмен опытом и исходниками между группами, то библиотека(исходник) просто копировалась в другой проект(продукт для друго клиента) и начинала жить самостоятельной жизнью, сохранив в себе все глюки и недоработки, которые присутствовали на момент копирования.
Для исправления ситуации было принято решение организовать репозиторий (хранилише) и систему сбора проекта с использованием набора библиотек общего кода(Пакетов).
В качестве инструмента для этого был выбран Maven, т. к. он по умолчанию выполняет схожие функции, имеет гибкий жизненный цикл и огромную гибкость плагинной системы.
Но обо всем по порядку
Главной проблемой, о которой я и не подозревал в начале своих изысканий, оказалось то, что Пакеты должны содержать в себе не скомпилированные в байт код файлы, а именно исходники, т.к. компиляция должна происходить именно под той версией «ядра», для которой они будут использоваться. Для простоты назовем наши прикладные исходники bpas. Это немного противоречит стандартному ЖЦ в Maven.
После таких откровений было принято решение формировать пакет из исходников, но при формировании обязательно проверять их атомарную компилируемость. Иными словами, задействовать почти стандартный ЖЦ Maven, когда сначала компилируются .class, а потом вместе с ресурсами запаковываются в jar. Только в моем случае Пакет вместо скомпилированных файлов формировался из запакованных в zip исходных bpas.
Немного о том как работает Maven
Жизненный цикл Maven достаточно полный, и набор фаз(phases) учитывает практически все этапы сборки проекта, которые могут потребоваться.
Причем пытаясь запустить какую-то фазу ЖЦ, например «mvn compile», я на самом деле запускаю всю цепочку фаз от validate (валидация проекта) до compile, не пропуская ни одной. Для каких-то фаз существуют так называемые плагины по умолчанию, которые будут вызваны несмотря на то, что в pom.xml(основной файл Maven проекта) существует только заголовок и ни одного указания на запуск плагинов.
Здесь стоит отдельно отметить тот факт, что Maven — это полностью плагинная система. Иными словами, он не умеет практически ничего, кроме запуска плагинов, а вот они уже умеют делать потрясающе много. Получается, что когда мы хотим научить Maven каким- то особенностям сборки проекта, мы должны добавить в pom.xml указание на запуск нужного плагина в нужную фазу и с нужными параметрами.
Вот такой абсолютно валидный пустой pom.xml, несмотря на свою пустоту, при получении команды mvn deploy запустит Плагин инициализации, компиляции, упаковки и деплоя Java исходников из папки src/main.
Основной политикой использования в Maven является то, что для любого действия есть свои параметры по умолчанию и дополнительные настройки требуются только в том случае, когда этих умолчаний не хватает или они грубо нарушаются. В моем случае пришлось отказаться от очень многих умолчаний, поэтому pom.xml уже не выглядит так скромно.
Построение нового ЖЦ в pom.xml
Для реализации пакетов был подобран следующий жизненный цикл.
initialize (инциализация) – Читаем настройки из конфиг(property или key = value) файла и добавляем их в тег properties. О теге properties поговорим чуть позже.
generate-sources (генерация исходного кода) – Загружаем и распаковываем из zip все Пакеты, которые являются зависимостями данного пакета/проекта, в отдельную директорию для последующей компиляции вместе с исходниками текущего пакета/проекта.
compile (компиляция) – Запускаем свой плагин компиляции для наших bpas, который определяет правильный порядок компиляции и запускает компилятор командной строки для нашего языка. Кратко я расскажу о собственном плагине ниже, но гайд по его написанию предлагаю вынести за пределы данной статьи.
assembly (сборка) – запаковываем пакет, состоящий из исходников bpas в zip с сохранением структуры подкаталогов исходных файлов.
deploy (в нашем случае выгрузка в репозиторий) – Собранный на фазе assembly zip отправляется в локальный репозиторий Maven с добавлением к нему pom.xml и другой информации по пакету. Данная процедура почти идентична нормальному deploy jar файла, но с особыми параметрами.
clean (очистка) – Данная фаза не входит в общий ЖЦ фаз сборки, а стоит несколько особняком, но поскольку она также была модернизирована, ее тоже стоит упомянуть. Кроме стандартного удаления директории, в которой лежат скомпилированные файлы. (targetDirectory), потребовалось удалять тот мусор, который образуется в процессе скачивания и распаковки пакетов-зависимостей.
Общая структура pom.xml
Я условно делю pom.xml на две части: заголовок и сборка.
Сборка (тег build) — это вторая часть pom.xml, в которой настраиваются особенности обработки той или иной фазы жизненного цикла различными плагинами с недефолтными настройками. Кроме этого там настраиваются директории и параметры, которые будут участвовать в сборке проекта:
sourceDirectory – директория, в которой находятся исходники для компиляции.
finalName – конечное имя файла после запаковки в архив.
directory – рабочая директория, в которую будут положены скомпилированные файлы.
Кроме этого еще раз хочу напомнить, что для всех этих параметров, существуют значения по умолчанию, и их отдельное указание в нашем случае требуется только потому, что они должны отличаться от этих самых умолчаний.
Реализация ЖЦ в теге build
Теперь вернемся к определенному нами ЖЦ и посмотрим, как каждая из фаз жизненного цикла реализована при помощи вызова нужного плагина с той конфигурацией, которая нам нужна.
initialize
Тут опять давайте немного отвлечемся и отдельно упомянем тег properties. Объясним, зачем он нужен и как используется.
Если говорить очень грубо, то этот тег похож на объявление констант, которые в дальнейшем будут использоваться в нашей программе (pom.xml). Но попадать туда значения могут тремя разными способами. И у каждого способа есть приоритет, определяющий, какое в итоге значение будет в тот момент, когда оно реально потребуется.
Низший приоритет у прямой записи свойств в тег properties, например так:
Более высокий приоритет у прямого задания параметров при запуске Maven, примерно так «mvn –DhelloText=Hi initialize»
При запуске Maven с таким параметром исходное значение тега helloText будет заменено на переданное в строке запуска для текущего сеанса, т.е. в xml оно не сохранится. Если такой константы вообще не существовало, то на этот сеанс она будет существовать и может быть использована. Значения всех несуществующих констант — пустая строка.
Наивысшим приоритетом обладает добавление значений в тег proprties плагинами в текущей сессии. Они так же не сохраняться в pom.xml. Именно этот механизм и будет использован нами для вынесения отдельных настроек сборки в properties файл, содержащий “имя=значение”
Для этого используется плагин properties-maven-plugin
Кроме интересного решения по вынесению зависимых от контекста настроек в отдельный файл здесь присутствует хорошая демонстрация того как один и тот же плагин запускается в совершенно разные фазы жизненного цикла. Это обеспечивается за счет тега , где для каждой нужной фазы создается отдельный тег . Тег должен включать в себя уникальный id(если execution больше одного), а так же может содержать отдельный тег configuration приоритет которого выше всех остальных.
generate-sources
На стадии генерации исходников мы рекурсивно загружаем из репозитория и распаковываем все необходимые нам Пакеты, которые указаны в зависимостях. Опять же самим практически ничего делать не нужно. Все за нас сделает плагин после указания ему правильных настроек.
Конструкция $ означает, что нужно взять значение из тега “/project/properties/packagesPath”.
Отдельно хочу отметить, что использования плагина maven-assembly-plugin для распаковки считается deprecated и не рекомендуется к использованию в Maven 3. Вместо него используется maven-dependency-plugin с настройками аналогичными указанным выше. Я же использую более старую версию плагина, чтобы еще раз наглядно показать, как один и тот же плагин настраивается на выполнение нескольких задач из его ассортимента.
compile
Со стадией компиляции пришлось изрядно повозиться, но основные трудности возникли с написанием собственного плагина компиляции. Пошаговая инструкция по написанию собственного плагина для Maven — это тема для отдельной статьи, поэтому сейчас мы не будем заострять на этом внимание. В конце-концов изложенный здесь материал может быть использован и для скриптовых языков, компиляция которым вообще не требуется.
Одно можно сказать наверняка, как бы вы не старались, не удастся отключить запуск родного плагина maven-compile-plugin, призвание которого компилировать исходники на Java( Не рассматривая возможности редактирования superPom.xml). Итак настройки моего плагина компиляции выглядят следующим образом:
используемые параметры:
protectionServer — сервер защиты, без которого невозможен запуск компилятора командной строки.
protectionAlias — секция используемой лицензии сервера защиты.
bpasccPath — полный или относительный путь к компилятору командной строки.
binaryVersion — Версия, которая будет «вмонтирована» в скомпилированную библиотеку.
Это далеко не все настройки моего плагина, но как я и говорил, это тема для отдельной большой статьи. В принципе секцию configuration можно было вообще не указывать и тогда все параметры, которые необходимы плагину, были бы проинициализированы плагином значениями по умолчанию, что соотвествует основной концепции Maven.
assembly
При прохождении фазы assembly у Maven по умолчанию настроен запуск maven-assembly-plugin, явно указав его запуск в фазе assembly в теге build, мы можем переопределить его настройки и заставить работать на нас. Этот же плагин мы использовали для распаковки пакетов перед компиляцией, поэтому теперь я приведу полную версию настроек этого плагина, включающую и запаковку и распаковку.
Здесь мы видим вторую секцию execution с и необходимую для этой фазы настройку ..\src.xml. В src.xml содержатся настройки того, как необходимо запаковать исходники. На самом деле все эти настройки можно поместить прямо в теге descriptor, но это может сильно загромоздить pom.xml.
Приведем пример src.xml для полноты картины.
packagesDirName — это константа из /project/properties файла pom.xml
Отдельно хочу отметить, что такое вынесение настроек запаковки в отдельный файл, позволило мне создать один конфиг запаковки на все Пакеты, что крайне удобно.
deploy
Фаза deploy так же запускается Maven'ом независимо от того, указали ли мы настройки этого плагина или нет. Переопределив их, мы и этот плагин заставили работать на себя.
С такими ручными настройками maven-deploy-plugin позволяет любой файл(или даже группу файлов) выложить в репозиторий Maven как валидную библиотеку(Пакет). Теперь разберем настройки по порядку.
file — файл, который будет отправлен в репозиторий Maven как Пакет.
url — путь к репозиторию Maven
repositoryId — идентификатор репозитория, в который будет производиться депллой.
groupId, artifactId, version — стандартная идентификация пакета в репозитории Maven. Именно по этим трем параметрам можно однозначно идентифицировать библиотеку. packaging – функционал деплой так же включает в себя запаковку файлов, которые будут отправлены в репозиторий, поэтому необходимо снова указать ему zip, чтобы он ничего не делал с пакетом, иначе распакует и запакует как jar :-).
pomFile – если данный параметр указан, то в комплект к Пакету будет добавлен тот файл, который мы укажем как pom.xml, при этом его изначальное имя может быть другим. Сохранять оригинальный pom.xml выгодно по многим причинам, поэтому мы не будем брезговать данной возможностью.
clean
Фаза clean, как я уже говорил, не входит в стандартный ЖЦ. Изначальная ее задача состоит в том, чтобы после выполнения команды mvn clean в проекте не осталось никаких следов жизнедеятельности. В нашем случае кроме стандартной папки targetSource(указана в теге build) требуется так же удалить все Пакеты, которые были «слиты» как зависимости для успешной компиляции пакета/проекта.
directory — собственно указание директории, которую необходимо удалить. Надо отметить, что тут создатели плагина отошли от общепринятой концепции, и явное указание настроек плагина не отменяет его действий по умолчанию. Но в данном случае, это очень хорошо, т. к. избавляет нас от лишний настроек.
Памятуя о том, как поначалу тяжело разбираться с отдельными ветками настроек, ниже приведу полный текст pom.xml одного из пакетов.
Итоги
- phase и goal их взаимосвязь между собой и плагинами.
- создание архитипов — шаблон проекта для быстрого развертывания своей конфигурации pom.xml и набора файлов по умолчанию.
- репозитории Maven и управление ими.
- как написать и отладить свой плагин для Maven.
- как НЕ писать свой плагин под каждый «чих».
Несмотря на то, что я сам остался чертовски доволен своей работой, я готов признать, что в данном виде система пакетной сборки проекта еще далека от совершенства, однако, приведенное описание достаточно иллюстрирует реализацию полного жиненного цикла пакета/проекта. Фактически это работоспособный каркас, поверх которого можно почти неограниченно расширять возможности.
От переводчика: Несколько лет назад я поставил себе целью быстро, но достаточно плотно познакомиться с таким повсеместно используемым фреймворком, как Apache Maven. Практически моментально мне удалось найти соответствующую литературу, но я был слегка удивлен тем фактом, что все комплексные материалы были исключительно на английском языке, на русском же была масса разрозненных статей, но полноценной книжки, которую можно было прочитать от корки до корки, мне обнаружить не удалось. Как результат, для прочтения я выбрал небольшую книжку «Introducing Maven», написанную Balaji Varnasi и Sudha Belida и выпущенную издательством Apress в 2014 году. По мере прорешивания всех задач у меня постепенно родился перевод этого издания, который хоть и пару лет пролежал у меня в столе, но возможно всё еще будет полезен сообществу.
Здесь я привожу перевод только одной из глав этой книги, а целиком её можно скачать вот по этим ссылкам на английском, или на русском языке (PDF).
Создание архетипов
Maven предоставляет несколько способов создать новый архетип. Здесь для этого мы будем использовать уже существующий проект.
1. Удалите все прочие ресурсы, такие как файлы, специфичные для Integrated Development Environment (IDE) (.project, .classpath и т.д.), которые вы не хотите включать в архетип.
2. Замените содержимое файла web.xml из папки webapp/WEB-INF. Это настроит веб-приложение на использование Servlet 3.0:
3. Добавьте зависимость Servlet 3.0 в файл pom.xml. Обновленное содержимое pom.xml отображено в Листинге 6-8.
Листинг 6-8. Файл pom.xml с Servlet Dependency
4. Т.к. мы будем вести разработку веб-проекта на Java, то создайте папку с именем java в директории src/main. Аналогично создайте папки test/java и test/resources в директории src.
5. Создайте файл AppStatusServlet.java, принадлежащий пакету com.apress.gswmbook.web.servlet в директории src/main/java. Пакет com.apress.gswmbook.web.servlet преобразуется в структуру папок com\apress\gswmbook\web\servlet. Исходный код файла AppStatusServelet.java отображен в Листинге 6-9.
Listing 6-9. Исходный код Java-класса AppStatusServlet
Прототипный проект по структуре будет поход на изображенный на Рис.6-5.
Рис. 6-5. Сгенерированный прототипный проект
Используя командную строку, перейдите в папку gswm-web-prototype проекта из выполните следующую команду:
Следующим шагом является перенос только что сгенерированного артефакта в отдельную папку gswm-web-archetype для его настройки перед публикацией. Для этого выполните следующие шаги:
1. Создайте папку gswm-web-archetype в директории C:\apress\gswm-book\chapter6.
2. Скопируйте поддиректории и файлы из папки C:\apress\gswm-book\chapter6\gswm-web-prototype\target\generated-sources\archetype в папку gswm-web-archetype.
3. Удалите поддиректорию target из папки C:\apress\gswm-book\chapter6\gswm-web-archetype.
Структура папок для gswm-web-archetype должна быть похожа на отображенную на Рисунке 6-6.
Рис. 6-6. Структура проекта веб-архетипа
Давайте начнем процесс модификации с файла pom.xml, расположенного в папке gswm-web-archetype\src\main\resources\archetype-resources. Измените finalName в файле pom.xml с gswm-web на $. В процессе создания проекта Maven заменит выражение $ значением, которое было предоставлено пользователем.
Когда проект создается из архетипа, Maven запрашивает у пользователя имя пакета. Maven создает структуру папок, соответствующую пакету, находящемуся в директории src/main/java созданного проекта. Затем Maven перемещает в этот пакет все содержимое из папки archetype-resources/src/main/java архетипа. Т.к. вы хотите, чтобы AppStatusServlet находился во вложенном пакете web.servlet, то создайте папку web/servlet и переместите AppStatusServlet туда. Новое расположение AppStatusServlet.java отображено на Рисунке 6-7.
Рис.6-7. AppStatusServlet в пакете web.servlet
Откройте AppStatusServlet.java и измените имя пакета с package $; на package $.web.servlet;
Завершающим шагом в создании архетипа является выполнение следующей команды из командной строки, находясь в папке gswm-web-archetype:
Итоги
Архетипы Maven являются заготовками проектов, позволяющими быстро запускать новые проекты. В данной главе для генерации сложных Maven-проектов, таких как веб-проекты или мультимодульные проекты, использовались встроенные архетипы. Также вы познакомились с созданием и использованием пользовательских архетипов.
В следующей главе вы познакомитесь с основами генерации сайта, создания документации и отчетов при помощи Maven.
Использование архетипов
Как только архетип был инсталлирован, то простейшим путем создать из него проект – это, находясь в папке C:\apress\gswm-book\chapter6, выполнить следующую команду:
В ответ на запросы Maven введите значения, указанные в Листинге 6-10, и вы увидите созданный проект.
Listing 6-10. Создание нового проекта с использованием архетипа
Т.к. файл pom.xml для test-project уже содержит плагин Tomcat, то для запуска проекта вызовите команду mvn tomcat7:run, находясь в папке C:\apress\gswmbook\chapter6\test-project. Откройте браузер и перейдите по адресу localhost:8080/test-project/status. Вы увидите надпись OK, как отображено на Рисунке 6-8.
Поговорим о Мавене
Сперва его нужно установить. Разумеется так как у меня мак, показать установку я смогу только для мака. Только вот незадача. Я его давно уже установил, поэтому вам придется сделать это самостоятельно :)Инструкция по установке Maven есть в этом материале. |
Maven Plugins
Хотел еще поговорить о плагинах, но статья и так уже вышла большая. Будет вам домашним заданием. Разберитесь, что это такое и как этим пользоваться. В продолжении статьи разберемся с Maven на практике.
Выполняем команды Мавена
- Скомпилировались наши исходники и поместили их в указанный путь.
- Команда прошла успешно — BUILD SUCCESS.
Глава 6: Архетипы Maven
До этого момента вы создавали проект Maven вручную, создавая папки и файлы pom.xml с нуля. Это может быть утомительным, особенно если вам часто приходится создавать проекты. Для решения этой проблемы Maven предоставляет архетипы. Архетипы Maven — это заготовки проектов, которые позволяют пользователям легко создавать новые проекты.
Архетипы Maven также предоставляют удобную базу для обмена опытом и обеспечивают постоянство стандартной структуры директорий Maven. Например, предприятие может создать архетип с корпоративной каскадной таблицей стилей (CSS), утвержденными библиотеками JavaScript и повторно используемыми компонентами. Разработчики, используя эти архетипы для создания проектов, будут автоматически следовать стандартам компании.
Зачем нам Мавен
- • подтянуть все необходимые библиотеки (в терминах инструментов для сборки — зависимостей (то есть dependency));
- • определить то, как именно нужно собирать проект и во что (например, хотим мы собирать в WAR или JAR или executable JAR);
- • задать версию проекта в одном месте так, чтобы при сборке была указана она;
- • описать проект и его жизненный цикл;
- • добавлять так называется плагины (калька с английского слова Plugin);
- • публиковать библиотеки в общем хранилище, чтобы другие проекты смогли подтянуть их как зависимости.
Встроенные архетипы
Maven прямо «из коробки» предоставляет разработчикам сотни архетипов. Кроме того, существует множество проектов с открытым исходным кодом предоставляющих дополнительные архетипы, которые можно скачать и использовать. Maven также предоставляет архетипы плагинов с целями для создания архетипов и генерации проектов из архетипов.
У плагина архетипов существует цель generate, позволяющая просматривать и выбирать необходимый архетип. Листинг 6-1 отображает результаты запуска цели generate из командной строки. Как видите, на выбор предоставлен 491 архетип (на 2018 год их уже было более 2 тысяч – прим.перев.). Использование нескольких из них рассматривается в этой главе.
Листинг 6-1. Вызов цели generate плагина архетипов Maven
ImageComparator:
Под это дело создадим тесты. Класс, который тестирует, должен находиться в том же пакете, только в src/test/java. Идея об этом знает, и можно воспользоваться ее возможностями. Для этого на имени класс в самом файле нажимаем мышкой, и на появившейся лампочке выбираем Create test:Нам предложат выбрать настройки для будущего теста. Ничего не ставим, просто жмем OK: Для нашего теста возьмем из тестовых картинок image-comparison и положим их в тестовые ресурсы (src/test/resource). После этого напишем два теста. Один будет проверять, что эти две картинки разные. А в другой передадим одинаковую картинку и будем ожидать ответ, что они одинаковые. После получим такой тест: Тесты очень простые, останавливаться на них не буду. Если вам это будет интересно, как-нибудь напишу статью о тестировании (напишите об этом в комментариях).
Мультимодульный проект
Проекты Java Enterpise Edition (JEE) часто разделяются на несколько модулей для облегчения разработки и поддержки. Каждый из этих модулей производит такие артефакты, как Enterprise JavaBeans (EJBs), веб-сервисы, веб-проекты и клиентские JAR. Maven поддерживает разработку таких больших JEE-проектов, позволяя размещать несколько Maven-проектов внутри другого Maven-проекта. Структура такого мультимодульного проекта отображена на Рисунке 6-3. Родительский проект обладает файлом pom.xml и несколькими Maven-проектами внутри.
Рисунок 6-3. Структура мультимодульного проекта
До конца этой главы мы объясним, как построить мультимодульный проект для задачи, в которой вам нужно разделить большой проект на веб-приложение (WAR-артефакт), предоставляющее пользовательский интерфейс, сервисный проект (JAR-артефакт), содержащий код сервисного слоя, и проект постоянства (Persistence), содержащий код уровня репозитория. На Рисунке 6-4 отображено визуальное представление такого сценария.
Рисунок 6-4. Мультимодульный проект Maven
Давайте начнём процесс с создания родительского проекта. Чтобы это сделать выполните следующую команду в командной строке в папке C:\apress\gswm-book\chapter6:
Архетип pom-root создает папку gswm-parent и в ней — файл pom.xml.
Как следует из Листинга 6-4, созданный файл pom.xml имеет минимальное содержимое. Заметьте, что в теге packaging родительского проекта указан тип pom.
Листинг 6-4. Родительский файл pom.xml
Теперь создайте веб-проект запуском следующей команды в папке C:\apress\gswm-book\chapter6\gswm-parent:
В процессе генерации этого веб-проекта вы предоставили Maven такие координаты, как groupId, version и др. в виде параметров, переданные в генерирующую цель, которая и создала проект gswm-web.
Следующим шагом будет создание сервисного проекта. Находясь в папке C:\apress\gswm-book\chapter6\gswm-parent выполните следующую команду:
Обратите внимание, что вы не указывали параметр package, т.к. maven-archetype-quickstart создает JAR-проект по умолчанию. Также обратите внимание на использование параметра interactiveMode. Он просто указывает Maven выполнять команду, не запрашивая у пользователя никакой информации.
Аналогично предыдущему шагу, создайте следующий Java-проект gswm-repository путем выполнения в папке C:\apress\gswm-book\chapter6\gswm-parent следующей команды:
Теперь, когда у вас сгенерированы все проекты, взгляните на файл pom.xml в папке gswm-parent. Листинг 6-5 отображает его содержимое.
Listing 6-5. Родительской файл pom.xml с модулями
Элемент modules позволяет объявлять дочерние модули в мультимодульном проекте. По мере генерации каждого модуля Maven регистрирует их в качестве дочерних. Кроме того, он модифицирует файлы pom.xml самих модулей, добавляя в них информацию о родительском pom.xml. Листинг 6-6 отображает файл pom.xml проекта gswm-web, в котором указан родительский pom-элемент.
Listing 6-6. Файл pom.xml веб-модуля
Теперь, когда вся инфраструктура установлена, можно собрать следующий проект. Просто запустите команду mvn package находясь в папке gswm-project, как отображено в Листинге 6-7.
Listing 6-7. Команда Maven package, запущенная в директории родительского проекта
Пишем исходники и тесты к нашему “проекту”
pom.xml всему голова
- • groupId — это идентификатор девелоперской организации или отдельного инженера. Обычно это домен в обратном порядке. Для примера здесь описан аккаунт romankh3 на гитхабе. Это очень важно. Скажем, у Spring экосистемы это com.springframework . Так можно отличить оригинальный проект от чьего-то ответвления или просто по совпадению имени проекта.
- • artifaceId — это уже имя конкретного проекта, который описывается в этом помнике.
- • version — версия этого проекта. Здесь все ясно, как божий день: добавил новый функционал, починил старый, отрефакторил или сделал какие-то еще изменения — версию увеличил.
- • packaging — здесь мы описываем, как Мавен должен собирать наш проект. То ли в Jar, то ли в War, то ли еще какие-то другие.
- • name — здесь уже более приятное для глаз название проекта.
Настраиваем pom.xml
Пока мы теоретизировали, получился вполне себе годный pom.xml: Смотреть код — Но, чтобы было что компилировать, его нужно добавить туда! Логично? — Да, капитан. бгг Поэтому добавим класс, в котором будет метод и два теста на него. Создадим обычную схему папок для Мавена:
В src/main/java создадим пакет, в котором будем работать. Чтобы составить его правильно, хорошо бы поставить в начало название организации ( groupId ), а потом имя проекта. В нашем случае это будет так: com.github.javarushcommunity.mavendemo Как по мне, то очень неплохой пакет. В нем создадим класс ImageComparator , к которому напишем два теста.
Maven lifecycle
- • compile — компилировать проект. Это первый этап: в ходе него можно посмотреть, нет ли ошибок компиляции в проекте. Иногда бывает разная чехарда с работой в IDEA, из-за чего появляются проблемы с компиляцией там, где их не должно быть. Так что эта команда расставит все точки над i.
- • test — запускает все тесты, которые работают над JUnit и находятся там, где их ожидает Мавен ( src/test/java ваш капитан).
- • package — это следующая команда, которая включает две предыдущие: то есть, внутри нее вначале запускается команда compile , потом на скомпилированный проект натравливается команда test , ну и если все ок и здесь, запускается создание архива (того архива, который мы выбираем в ))
- • install — когда мы устанавливаем Мавен на машину, у нас появляется локальный гит-репозиторий, в котором хранятся библиотеки, которые мы скачиваем для проектов. Но прелесть Мавена заключается еще и в том, что мы при помощи команды install можем добавить наш проект в локальный гит-репозиторий и локально использовать наш проект как зависимость. Не верите? Попробуйте :) Таким образом можно достаточно быстро посмотреть, как будет выглядеть ваш проект как зависимость у другого.
- • deploy — это венец всего, что было до этого. Команда, которая дарит возможность добавлять проект не только в локальный репозиторий как install, но и на удаленный, откуда каждый человек с доступом сможет использовать его как зависимость.
- • verify — команда, которая все проверит и скажет, готов ли проект к деплою.
- • clean — разумеется, скомпилированные файлы и архив где-то должны храниться. Для этого у Мавена есть папка target . Это данные, которые проекту не нужны. И перед тем, как собирать проект заново, хорошо бы удалить все, что было до этого. Вот для этого и служит команда clean .
Подключаем Мавен и проект в целом к IDEA
- Сказать идее, где будут исходники кода, а где будут тесты.
- Добавить мавен проект в идею.
- • src/main/java — Sources
- • src/main/resources — Resources
- • src/test/java — Tests
- • src/test/resources — Test Resources
- • target — Excluded
Создание Веб-проекта
Maven предоставляет архетип maven-archetype-webapp, позволяющий сгенерировать веб-приложение. Давайте создадим такое приложение путем вызова следующей команды в папке C:\apress\gswm-book\chapter6:
Эта команда выполняется в интерактивном режиме. На поступающие вопросы введите следующую информацию:
Сгенерированная структура папок должна походить на ту, что изображена на Рисунке 6-1:
Рисунок 6-1. Структура веб-проекта Maven
Файл pom.xml минимален и содержит единственную зависимость — JUnit. Maven может упростить запуск вашего веб-приложения, используя встроенные веб-серверы, такие как Tomcat или Jetty. Листинг 6-2 отображает модифицированный файл pom.xml с добавленным плагином Tomcat.
Листинг 6-2. Модифицированный файл pom.xml с внедренным плагином Tomcat
Для того, чтобы запустить это веб-приложение на сервере Tomcat вызовите следующую команду в корневой директории проекта:
Вы увидите развернутый проект и вывод, похожий на изображенный на Листинге 6-3.
Листинг 6-3. Вывод команды Tomcat run
Теперь запустите браузер и перейдите по адресу localhost:8080/gswm-web/. Вы должны увидеть веб-страницу, подобную изображенной на Рисунке 6-2.
Рисунок 6-2. Веб-проект, запущенный в браузере
Читайте также:
- Почему для обработки текстовой информации на компьютере используется 256 символов
- Есть ли у ростелекома тарифы для телефона
- Касперский что значит отложено
- Организация принципы построения и функционирования компьютерных сетей
- Определите максимальную глубину цвета в битах на пиксель которую можно использовать при фотосъемке