...
...

Автоматизация процесса разработки Java–приложений с помощью Maven 2

Вероятно самое сложное в процессе разработки Java–приложений — это начать. Необходимо принять множество важных решений. Где будет храниться исходный код? Где разместить unit–тесты? Где хранить необходимые jar–библиотеки? Каким образом проект будет собираться, тестироваться, документироваться и развертываться? От этих решений зависит весь остальной процесс разработки приложения — насколько он будет удобным и не будет ли отнимать слишком много времени на выполнение одних и тех же операций для каждого билда. От этих решений также будет зависеть, насколько вы хороши как архитектор программного обеспечения.

Существует ряд инструментов, которые позволяют автоматизировать процесс сборки проектов, например, Ant ( сайт ). Ant уже достаточно продолжительный период времени является одним из незаменимых инструментов для большинства разработчиков. В свое время, Ant был представлен как революционный проект, который помог Java–разработчикам забыть слово make. Для тех, кто не знаком с программой make, достаточно будет сказать, что это не самое лучшее решение для сборки Java–проектов, поскольку она платформозависимая и не совсем простая в использовании. С выходом Ant разработчики получили платформонезависимый инструмент, который использует конфигурационный XML–файл build.xml. Ant долгое время был на пике популярности, но и у него были свои слабые места. Написание конфигурационного файла build.xml — это достаточно сложный процесс, где необходимо полностью знать синтаксис и структуру команд и блоков. И естественно, время, потраченное на изучение Ant и формата его
конфигурационного файла, лучше было бы потратить на непосредственно разработку проекта.

Maven, достаточно молодой проект, каким в свое время был Ant. Maven версии 1.0 вышел несколько лет назад и был принят широкой аудиторией разработчиков, как достойная замена Ant. Однако он принес с собой не так уж много отличий от старого конфигурационного файла build.xml. Maven 1.0 был медленный и не совсем удобный, поэтому процесс был очень схож с тем, с чем приходилось сталкиваться при работе с Ant. Фактически, Ant был ядром для Maven 1.0. И вот сейчас, мы имеем практически полностью переписанный, новый Maven 2.0.

Достоинства Maven 2.0

Maven 2.0 имеет ряд существенных преимуществ перед своими предшественниками. Кроме того, он предоставляет средства не только для сборки проектов. Если вы только что приступили к созданию нового Java–проекта и хотите стартовать быстро, Maven 2.0 сделает все за вас за считанные минуты. Вот некоторые из достоинств Maven 2.0:

. Стандартизированная схема проекта и генератор структуры проекта.
. Стандартизированный механизм управлением зависимостями в проекте.
. Поддержка нескольких проектов.
. Немедленная загрузка новых плагинов при первой необходимости.
. Автоматическая генерация веб–сайта для обновления последней информации о проекте.
. Интеграция с самыми популярными инструментами управления исходным кодом CVS и Subversion (SVN).

Уже это позволяет сказать, что Maven 2.0 — достойный выбор в качестве системы управления сборкой проектов. Теперь, когда мы разобрались что такое Maven 2.0, можно приступить к более детальному исследованию возможностей этого инструмента.

Первые шаги

Первое, что нам нужно сделать — это настроить структуру директорий проекта. Как вы могли догадаться, руками это делать не придется. Maven поможет все сделать автоматически, в зависимости от того, какой тип проекта вы собираетесь разрабатывать. Как только вы загрузили и распаковали дистрибутив с крайней версией Maven 2.0, необходимо добавить директорию bin из дистрибутива Maven в переменную окружения вашего системного пути (PATH в Windows XP). Для того, чтобы протестировать свежеустановленный дистрибутив, можно запустить команду mvn –version из командной строки.

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

mvn archetype:create –DgroupId=com.litvinyuk –DartifactId=my–app

После выполнения этой команды, мы имеем следующую структуру директорий:

Все предельно просто. Следует еще раз напомнить, что вы можете изменить структуру создаваемых директорий, написав свой собственный архетип. Но не рекомендуется слишком далеко отходить от канонической структуры представленной выше, одно из основных достоинств Maven — это стандартная структура проектов. Структура директорий содержит два дерева исходного кода: одно для исходного кода самого Java–приложения, второе — для кода unit–тестов. Также вы могли заметить, когда в первый раз запустили Maven, что он загружал чего–то из Интернета. Maven будет постоянно обновлять себя соответствующими функциональностями на основе плагинов, которые вы используете при старте, если это необходимо. По умолчанию, Maven загружает свои обновления из репозитория сайта Ibiblio ( сайт ). Вы можете изменить удаленный репозиторий, с помощью соответствующих настроек в директории conf дистрибутива Maven.

Кроме того, вы могли заметить, что Maven создал новый файл pom.xml в директории my–app. Этот файл определяет модель работы Maven с вашим приложением. Инструкции из этого файла дают знать Maven, каким образом должен собираться ваш проект, а также может включать другие специальные инструкции. (POM — это акроним от "project object model"). По–умолчанию, Maven также включает в себя JUnit, чтобы обеспечить возможность написания и выполнения unit–тестов для вашего приложения.

<project xmlns="httр://maven.apache.org/POM/4.0.0" xmlns:xsi="httр://www.w3.org/2001/XMLSchema–instance"
xsi:schemaLocation="httр://maven.apache.org/POM/4.0.0 httр://maven.apache.org/maven–v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.litvinyuk</groupId>
<artifactId>my–app</artifactId>
<packaging>jar</packaging>
<version>1.0–SNAPSHOT</version>
<name>Maven Quick Start Archetype</name>
<url>httр://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Теперь, когда мы создали структуру нашего проекта, мы можем добавить в него код и начать применять приемы из набора возможностей Maven. Следующие команды должны обязательно выполняться в той же директории, где находится файл pom.xml:

. mvn test — запускает тесты JUnit вашего приложения.
. mvn package — создает JAR–архив с вашим проектом.
. mvn install — добавляет JAR–архив с вашим проектом в репозиторий для использования в качестве библиотеки, если необходимо.
. mvn site — создает веб–сайт проекта.
. mvn clean — очищает целевую директорию от созданных в процессе сборки файлов.
. mvn idea:idea — создает файл проекта IntelliJ IDEA.

Рассмотрим более простой пример. Начать веб–проект на Java вручную может быть более продолжительной по времени задачей, чем начать обыкновенный Java–проект. Однако для Maven эта задача ничуть не сложнее предыдущей. Ниже приведен пример, который создает структуру директорий веб–проекта.

mvn archetype:create –DgroupId=com.litvinyuk –DartifactId=WebSample –DarchetypeArtifactId=maven–archetype–webapp

В результате, структура директорий будет выглядеть следующим образом:

На этот раз наш проект выглядит несколько иначе. В частности теперь у нас есть директория для веб–ресурсов, которые впоследствии будут включены в WAR–файл веб–приложения. Файл pom.xml также будет содержать строчку, которая будет определять, что проект должен быть упакован в WAR–файл: <packaging>war</packaging>. Теперь мы может создать WAR–файл проекта с помощью команды mvn package. Можете не волноваться по поводу того, каким образом нужно добавлять необходимые библиотеки в директорию WEB–INF/lib, Maven автоматически включит их в проект. Кроме того, мы очень просто можем изменить имя WAR–файла, добавив следующие строки в конфигурационный файл pom.xml:

<build>
<finalName>NewWebApplicationProject</finalName>
</build>

Управление зависимостями

После того как мы создали структуру директорий нашего проекта, написали немного кода, протестировали и скомпилировали наше приложение, пришло время разобраться с тем, как Maven управляет зависимостями в проекте. Для того, чтобы добавить библиотеку в ваш проект, необходимо прописать ее в файле pom.xml, при следующем запуске Maven автоматически загрузит необходимую библиотеку из репозитория Ibiblio и добавит ее в путь сборки проекта.

Если несколько важных вещей, касающихся зависимостей, о которых нужно помнить. Самое большое неудобство связано с .jar–файлами Права на них принадлежат Sun и из–за этого они не доступны через репозиторий Maven. Это связано с ограничениями, которые Sun накладывает на распространение своего кода. Очень надеемся, что очень скоро Sun раскроет исходный код Java и передаст его сообществу. Для того чтобы обойти эту проблему, вы можете скачать и установить необходимые библиотеки в вашем локальном репозитории или объявить библиотеку как внешнюю и указать ее местонахождение в файловой системе.

Вторая проблема, связанная с зависимостями, возникает тогда, когда необходимая библиотека вышла совсем недавно и ее еще нет в удаленном репозитории. Или у вас нет выхода в Интернет и вы бы хотели хранить все необходимые библиотеки на локальной машине. Здесь наилучшим вариантом будет создать собственный локальный репозиторий. Также удобно хранить ваш локальный репозиторий на веб–сервере, таким образом остальные члены команды разработчиков смогут им воспользоваться по необходимости. Чтобы поменять путь к репозиторию нужно просто внести изменения в файл settings.xml в директории conf из дистрибутива Maven.

Работать с зависимостями в Maven достаточно просто. Довайте рассмотрим пример добавления зависимости (библиотеки) в наш конфигурационный файл pom.xml. Выше, мы уже добавили JUnit в проект, сейчас мы добавим в наш проект библиотеку Quartz ( сайт ). Quartz — это open–source механизм для организации выполнения задач по расписанию, полностью написанный на Java.

<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.1</version>
<scope>compile</scope>
</dependency>

Это все, что нам нужно добавить в элемент <dependencies>, чтобы Maven загрузил библиотеку Quartz и включил ее как зависимость в наш проект. Не нужно волноваться по поводу зависимостей самой библиотеки Quartz. Репозиторий Maven содержит всю необходимую информацию о зависимостях зависимостей и вместе с Quartz будут загружены все необходимые ей библиотеки. Чтобы определить находится ли версия 1.5.1 библиотеки Quartz в репозитории Ibiblio, мы можем посмотреть репозиторий Maven здесь: сайт . Обратите внимание на параметр scope; с его помощью Maven определяет, на каком этапе необходима та или иная зависимость. В случае с JUnit, мы используем значение test для этого параметра, это говорит Maven, что эта зависимость необходима только на этапе тестирования, а не на этапе выполнения приложения.

Вот перечень доступных значений параметра scope:
. compile: это значение используется по умолчанию. Оно означает, что этот ресурс должен быть доступен при выполнении всех задач.
. test: ресурс доступен при выполнении тестов.
. runtime: означает, что этот ресурс должен использоваться на этапе выполнения приложения.
. provided: это значение используется для библиотек, которые должны входить в JDK или быть в переменной окружения CLASSPATH

Теперь нужно разобраться, что делать с библиотеками Sun, которые мы не сможем найти в удаленном репозитории. Нам нужно установить их в локальном репозитории с помощью Maven вручную. Можете не беспокоиться — звучит это гораздо сложнее, чем есть на самом деле. В качестве примера, мы установим библиотеку Java Activation Framework. Сначала необходимо загрузить ее с веб–сайта Sun, после чего с помощью Maven импортировать в наш локальный репозиторий. Кроме того, вы также можете установить отсутствующую библиотеку (.jar–файл) в Ibiblio самостоятельно. Для этого, вы можете воспользоваться инструкциями, которые располагаются по адресу: сайт .

mvn install:install–file –Dfile=activation.jar
–DgroupId=javax.activation –DartifactId=activation
–Dversion=1.0 –Dpackaging=jar

После выполнения этой команды, .jar–файл устанавливается в наш локальный репозиторий и может быть использован в проектах. Единственное, что нам осталось сделать, чтобы включить эту библиотеку в проект — это добавить описание в конфигурационный файл проекта. Не забывайте правильно указывать информацию о версиях библиотек при установке в репозиторий и при объявлении в конфигурационном файле. Если информация о версии библиотеки будет расходиться, то Maven просто не найдет ее и не сможет использовать. Информацию о стандартном именовании параметров при импортировании библиотек от Sun вы можете найти по этому адресу: сайт . Не забывайте также, что вы не можете публиковать и распространять эти .jar–файлы через репозиторий или другим способом, не нарушая лицензионное соглашение компании Sun.

<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>

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

Настройка репозиториев

Было бы совсем неудобно, если бы каждому разработчику приходилось настраивать свой собственный репозиторий в директории conf. Поэтому Maven может работать сразу с несколькими репозиториями в одно и то же время и все они должны быть прописаны в конфигурационном файле pom.xml. Рассмотрим пример конфигурирования нескольких репозиториев для нашего приложения. В следующей выдержке из файла pom.xml мы определяем для Maven два репозитория, в которых он будет искать необходимые зависимости. Ibiblio — это всегда репозиторий по умолчанию для Maven, но мы добавили еще один дополнительный репозиторий Panel Mirror. Кроме того, мы можем в качестве второго репозитория задать свой локальный веб–сервер, которым сможет пользоваться вся ваша команда разработчиков.

<repositories>
<repository>
<id>Ibiblio</id>
<name>Ibiblio</name>
<url>httр://www.ibiblio.org/maven/</url>
</repository>
<repository>
<id>PlanetMirror</id>
<name>Planet Mirror</name>
<url>httр://public.planetmirror.com/pub/maven/</url>
</repository>
</repositories>

Собираем несколько проектов из одного файла pom.xml

Достаточно часто компании, производящие программное обеспечение, сталкиваются с необходимостью разделять один продукт на несколько проектов. Т.е. конечный продукт будет собираться из нескольких связанных друг с другом проектов. Это не простая задача, учитывая необходимость постоянно следить за зависимостями и связями этих проектов при сборке в монолитный продукт. Однако с помощью Maven, все становится куда проще и понятнее. Для этого вам нужно просто создать родительский конфигурационный файл pom.xml, в котором вы определяете ссылки на другие модули проекта. В итоге, Maven построит проект без поблем, с использованием всех зависимостей и сторонних модулей. Механизм работы управления зависимостями анализирует содержимое конфигурационных файлов pom.xml каждого из модулей приложения и будет собирать части проекта в том порядке, в котором они друг от друга зависят. Порядок, в котором вы объявляете модули в родительском конфигурационном файле pom.xml не имеет значения, если в каждом из проектов все зависимости строго заданы. Однако, чтобы избежать неприятных сюрпризов, например, когда вы забыли что–то связать вручную в конфигурационных файлах, лучше соблюсти порядок объявления модулей таким, в котором они должны собираться. Рассмотрим пример. Наш родительский конфигурационный файл pom.xml выглядится следующим образом:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.litvinyuk</groupId>
<version>1.0–SNAPSHOT</version>
<artifactId>my–app</artifactId>
<packaging>pom</packaging>
<modules>
<module>Common</module>
<module>Utilities</module>
<module>Application</module>
<module>WebApplication</module>
</modules>
</project>

Теперь нам нужно быть увенными, что все три .jar–файла будут включены в модуль WebApplication, который их использует. Поэтому нам нужно объявить их как зависимости. В нашем примере, проект Utilities зависит от проекта Common, поэтому нам нужно добавить эту зависимость в объявление проекта Utilities. Тоже самое нужно сделать с объявлением проекта Application, который будет зависеть от проектов Utilities и Common. Если бы у нас было, например, 60 модулей, каждый из которых зависел бы от других, это бы значительно осложнило жизнь разработчика, который приступит к поддержке проекта, потому что было бы очень сложно разобраться, какой из проектов на какой "завязан". Поэтому нужно тщательно описывать все взаимосвязи между проектами в родительском файле pom.xml.

Зависимости модуля Utilities:

<dependencies>
<dependency>
<groupId>com.litvinyuk</groupId>
<artifactId>Common</artifactId>
<version>1.0–SNAPSHOT</version>
</dependency>
</dependencies>

Теперь мы устанавливаем зависимости модуля Application:

<dependencies>
<dependency>
<groupId>com.oreilly</groupId>
<artifactId>Common</artifactId>
<version>1.0–SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.litvinyuk</groupId>
<artifactId>Utilities</artifactId>
<version>1.0–SNAPSHOT</version>
</dependency>
</dependencies>

И, наконец, зависимости головного модуля приложения WebApplication:

<dependencies>
<dependency>
<groupId>com.litvinyuk</groupId>
<artifactId>Common</artifactId>
<version>1.0–SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.litvinyuk</groupId>
<artifactId>Utilities</artifactId>
<version>1.0–SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.litvinyuk</groupId>
<artifactId>Application</artifactId>
<version>1.0–SNAPSHOT</version>
</dependency>
</dependencies>

Крайнее, что нам нужно сделать — это добавить во все дочерние конфигурационные файлы pom.xml наших модулей элемент, который говорит, что этот файл явлется частью одной сборки:

<parent>
<groupId>com.litvinyuk</groupId>
<artifactId>my–app</artifactId>
<version>1.0–SNAPSHOT</version>
</parent>

В одной директории с родительским файлом pom.xml должны располагаться директории: Common, Utilities, Application и WebApplication. Теперь, когда мы будет запускать команду mvn package в директории с родительским файлом pom.xml, Maven соберет все необходимые проекты в том порядке, в котором они друг от друга зависят.

Плагины и Отчеты

На сегодняшний день существует большое количество различных плагинов для Maven 2.0. К сожалению, поскольку Maven был полностью переписан, плагины Maven 1.0 не будут работать с Maven 2.0. Однако пробел постепенно восполняется и уже сегодня есть достаточно переписанных и заново созданных плагинов для Maven 2.0. Ниже приведен пример конфигурации плагина в файле pom.xml, который взят с официального сайта Maven 2.0. Этот плагин используется для настройки опций компилятора:

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven–compiler–plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>

Существуют специальные плагины, предназначенные для создания различных отчетов. Эти отчеты создаются во время генерации веб–сайтов проекта с помощью команды mvn site. Пример конфигурации одного из таких плагинов с помощью элемента <reporting>:

<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven–project–info–reports–plugin</artifactId>
</plugin>
</plugins>
</reporting>

Maven Plugin Matrix ( сайт ) — очень полезный ресурс, где вы можете найти нужный плагин для любой из версий Maven.

Вывод

Maven 2.0 действительно очень функциональный инструмент для сборки проектов. Наиболее яркие достоинства Maven — это стандартные структуры директорий проектов и возможность развертывания проектов. Благодаря этому, разработчикам, переходящим от проекта к проекту, нет необходимости постоянно разбираться в структуре проекта и в процессе его сборки. Maven можно настроить таким образом, чтобы он автоматически собирал проект в определенное время и рассылал различные оповещения всем заинтересованным пользователям. Благодаря функциям документирования, вы можете постоянно отслеживать процесс разработки проекта на веб–сайте проекта, который генерируется автоматически с помощью Maven.

Нет никаких сомнений, что очень скоро Maven 2.0 вытеснит Ant. Maven имеет куда больше возможностей для удобного и простого в использовании процесса сборки и управления проектами.

Официальный веб–сайт проекта Maven ( сайт )

По материалам Chris Hardin.

Алексей Литвинюк, litvinuke@tut.by

© Компьютерная газета

полезные ссылки
Корпусные камеры видеонаблюдения