среда, 2 декабря 2009 г.

Maven - Использование библиотек, которых нет в официальных репозитариях

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

Когда я переводил на Maven свой первый проект я столкнулся с большой проблемой - а где взять библиотеки, которые не представлены в официальном maven репозитарии, но от которых зависит проект? Честно признаться в первый момент меня этот вопрос поставил в тупик и пришлось призвать на помощь накомых maven-оводов.

Сначала немного теории. Для разрешения зависимостей в Maven используются репозитарии зависимостей, где размещены собранные версии различных библиотек и приложений. При этом в большинстве репозитариев все эти бобилиотеки содержат специальную мета-информацию о своих зависимостях, в формате понятно Maven. Поэтому вы можете в своем проекте сказать что ваше приложение использует API сервера jetty и Maven при сборке автоматическе выкачает сам jetty указанной версии и необходимые для его работы зависимоcти.

Maven репозитариев достаточно много, перечислю только несколько наиболее популярных:

Самым большим конечно яляется основной репозитарий, там собрана огромная коллекция Java библиотек, она регуряно обновляется и имеет метаинформацию. Но там есть не все. В таких случая нужную библиотеку иногда можно найти в каком-то специализированном репозитарии, тут вам на помощь придет MVNRepository, Maven Search или другой поисковик Maven артифактов, таких сайтов сейчас не один десяток.

И все-же бывают случаи когда нужной библиотеки в репозитариях нет или вы используете какие либо библиотеки собственной разработки. Тут вам на помощь придет локальный и проектный/корпоративный репозитарий. Разберемся что это такое.

Локальный репозитарий
Такой репозитарий создается на локальной машине с целью кеширования артифактов, выкачиваемых из вышестоящих репозитариев. Поэтому первая сборка Maven проекта идет так долго - необходимо скачать зависимости проекта из внешнего репозитария, а потом и зависимости зависимостей. Таким образом локальный репозитарий быстро разрастается до размеров в несколько гигабайт. Полезно знать где он находится и как перенести его на другой диск.

Настройки репозитария находятся в файле settings.xml, который хранится в домашней папке пользователя ($HOME/.m2 для Linux и $USER_HOME/.m2 для Windows.
Путь к локальному репозитарию задается переменной localRepository и по умолчанию репозитарий находится в папке .m2

Для установки собранных артифактов в локальный репозитарий необходимо выполнить команду mvn install. Для установки в локальный репозитарий кастомных библиотек необходимо использовать расширенный синтаксис поканды install:

mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc -Dversion=11.1.0.7.0 -Dpackaging=jar -Dfile=ojdbc6.jar

Тут мы задаем группу, к которой будет относиться библитека, её идентифкатор, версиию и собственно сам файл.

Чтобы указать эту библиотеку в заивисмостях необходимо написать следующее:


<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>11.1.0.7.0</version>
</dependency>


Недостатки:
  • Репозитарий локален, другие разработчики не имею к нему доступ
  • На другом компьютере использовать нельзя
  • Проблемы на серверах автосборки
  • Нет централизованного места для хранения стабильных версий компонентов проекта
Плюсы:
  • Не требует настройки, администрирования
  • Прост в использовании

На одном из проектов мы некоторое время использовали локальные репозитарии для хранения custom-артифактов, в svn-репозитарии у нас была отдельная папка extlib и bat-файл, который при запуске деплоил все эти библиотеки в локальный репозитарий. Но проблемы с серверами автосборки и необходимость писать письмо на команду "Запустите batник перед сборкой" после каждого обновления библиотеки пересилило лень и мы развернули проектный Maven репозитарий.

Проектный / корпоративный репозитарий

В определенный момент функционал локального репозитария перестает устраивать и начинаются поиски более функционального решения. Тут ваиантов несколько:
  • расшарить папку с репозитарием, и настроить maven на остальных компьютерах на использование этого расшаренного репозитария
  • развернуть свой Maven репозитарий

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

Сейчас существует большое количество продуктов (как закрытых и клатных, так и Open Source), позволяющих развернуть свой Maven репозитарий. Приведу ссылки на некоторые: Apache Archiva, Artifactory, Nexus и другие.
Сейчас я не буду описывать настройку этих продуктов, скажу только что на развертывание Archiva я потрали часа 3.

Для того чтобы задеплоить кстомную библитоеку в репозитарий необходмо будет выполнить следующую команду:

mvn deploy:deploy-file -DgroupId=com.oracle -DartifactId=ojdbc -Dversion=11.1.0.7.0 -Dpackaging=jar -Dfile=ojdbc6.jar -DrepositoryId=archiva -Durl=http://mavenrep:8889/archiva/repository/oracle

Здесь мы указываем:
  • Группу библиотеки
  • Её идентификатор
  • Версию
  • Расположение на диске
  • Адрес репозитария

Для использования в зависимостях необходимо подлючить этот репозитарий к проекту, для этого добавляем:


<repositories>
<repository>
<id>oracle</id>
<url>http://mavenrep:8889/archiva/repository/oracle</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>


После этого декларация зависимости не будет отличаться от предыдущего примера.

Maven репозитарии кроме всего проечего предлагают и некоторые дополнительные функции:
  • Прокси для вышестоящих репозитариев
  • Поиск по репозитарию
  • Права доступа
  • и другие

Заключение:

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

И один раз настроив репозитарий - вы решаете большинство проблем с управлением зависимостей и можете сосредоточиться на разработке.