410013796724260
• Webmoney
R335386147728
Z369087728698
Maven зависимости, dependencyРедко когда какой-либо проект обходится без дополнительных библиотек. Как правило, используемые в проекте библиотеки необходимо включить в сборку, если это не проект OSGi или WEB (хотя и для них зачастую приходится включать в проект отдельные библиотеки). Для решения данной задачи в maven-проекте необходимо использовать зависимость dependency, устанавливаемые в файле pom.xml, где для каждого используемого в проекте артефакта необходимо указать :
Параметры GAV
Значения идентификаторов groupId и artifactId подключаемых библиотек практически всегда можно найти на сайте www.mvnrepository.com. Если найти требуемую библиотеку в этом репозитории не удается, то можно использовать дополнительный репозиторий http://repo1.maven.org/maven2. Cтруктура файла pom.xml и описание секции подключения к проекту репозитория представлены на главной странице фреймворка maven. Объявление зависимостей заключено в секции <dependencies>...</dependencies>. Количество зависимостей не ограничено. В следующем примере представлено объявление зависимости библиотеки JSON, в которой используется классификатор classifier (в противном случае библиотека не будет найдена в центральном репозитории) : <dependencies> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> <dependencies> Классификатор classifierКлассификатор classifier используется в тех случаях, когда деление артефакта по версиям является недостаточным. К примеру, определенная библиотека (артефакт) может быть использована только с определенной JDK (VM), либо разработана под windows или linux. Определять этим библиотекам различные версии – идеологически не верно. Но вот использованием разных классификаторов можно решить данную проблему. Значение classifier добавляется в конец наименования файла артефакта после его версии перед расширением. Для представленного выше примера полное наименование файла имеет следующий вид : json-lib-2.4-jdk15.jar. Расположение артефакта в репозиторииВ maven-мире «оперируют», как правило, артефактами. Это относится и к создаваемому разработчиком проекту. Когда выполняется сборка проекта, то формируется наименование файла, в котором присутствуют основные параметры GAV. После сборки этот артефакт готов к установке как в локальный репозиторий для использования в других проектах, так и для распространения в public-репозитории. Помните, что в начале файла pom.xml указываются параметры GAV артефакта : <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.examples</groupId> <artifactId>example1</artifactId> <version>1.0</version> <packaging>jar</packaging> ... </project> Формально координата артефакта представляет четыре слова, разделенные знаком двоеточия в следующем порядке groupId:artifactId:packaging:version. Полный путь, по которому находится файл артефакта в локальном репозитории, использует указанные выше четыре характеристики. В нашем примере для зависимости JSON это будет "HOME_PATH/.m2/repository/net/sf/json-lib/json-lib/2.4/json-lib-2.4-jdk15.jar". Параметру groupId соответствует директория (net/sf/json-lib) внутри репозитория (/.m2/repository). Затем идет поддиректория с artifactId (json-lib), внутри которой располагается поддиректория с версией (2.4). В последней располагается сам файл, в названии которого присутствуют все параметры GAV, а расширение файла соогласуется с параметром packaging. Здесь следует заметить, что правило, при котором «расширение файла с артефактом соответствует его packaging» не всегда верно. К примеру, те, кто знаком с разработкой enterprise приложений, включающих бизнес-логику в виде ejb-модулей и интерфейса в виде war-модулей, знают, что модули ejb-внешне представляют собой обычный архивный файл с расширением jar, хотя в теге packaging определено значение ejb. В каталоге артефакта, помимо самого файла, хранятся связанные с ним файлы с расширениями *.pom, *.sha1 и *.md5. Файл *.pom содержит полное описание сборки артефакта, а в файлах с расширениями sha1, md5 хранятся соответствующие значения MessageDidgest, полученные при загрузке артефакта в локальный репозиторий. Если исходный файл в ходе загрузки по открытым каналам Internet получил повреждения, то вычисленное значения sha1 и md5 будут отличаться от загруженного значения. А, следовательно, maven должен отвергнуть такой артефакт и попытаться загрузить его из другого репозитория. Область действия зависимости, scopeОбласть действия scope определяет этап жизненного цикла проекта, в котором эта зависимость будет использоваться. test compile provided runtime system <dependencies> <dependency> <groupId>ru.carousel</groupId> <artifactId>carousel-lib</artifactId> <version>1.0</version> <scope>system</scope> <systemPath> /projects/libs/carousel-lib.jar </systemPath> </dependency> </dependencies> Версия SNAPSHOTПри определении версии релиза можно использовать SNAPSHOT, который будет свидетельствовать о том, что данный артефакт находится в процессе разработки и в него вносятся постоянные изменения, например делается bugfixing или дорабатывается функционал. В этом случае код и функциональность артефакта последней сборки в репозитории могут не соответствовать реальному положению дел. Таким образом нужно четко отделять стабильные версии артефактов от не стабильных. Связываясь с нестабильными артефактами нужно быть готовыми к тому, что их поведение может измениться и наш проект, использующий такой артефакт, может вызывать исключения. Следовательно, нужно определиться с вопросом: нужно ли обновлять из репозитория артефакт, ведь его номер формально остался неизменным. Если версия модуля определяется как SNAPSHOT (версия 2.0.0-SNAPSHOT), то maven будет либо пересобирать его каждый раз заново вместо того, чтобы подгружать из локального репозитория, либо каждый раз загружать из public-репозитория. Указывать версию как SNAPSHOT нужно в том случае, если проект в работе и всегда нужна самая последняя версия. Транзитивные зависимостиНачиная со второй версии фреймворка maven были введены транзитивные зависимости, которые позволяет избегать необходимости изучения и определения библиотек, которые требуются для самой зависимости. Maven включает их автоматически. В общем случае, все зависимости, используемые в проекте, наследуются от родителей. Ограничений по уровню наследований не существует, что, в свою очередь, может вызвать их сильный рост. В качестве примера можно рассмотреть создание проекта «A», который зависит от проекта «B». Но проект «B», в свою очередь, зависит от проекта «C». Подобная цепочка зависимостей может быть сколь угодно длинной. Как в этом случае поступает maven и как связан проект «A» и c проектом «C». В следующей табличке, позаимствованной с сайта maven, представлен набор правил переноса области scope. К примеру, если scope артефакта «B» compile, а он, в свою очередь, подключает библиотеку «C» как provided, то наш проект «A» будет зависеть от «C» так как указано в ячейке находящейся на пересечении строки «compile» и столбца «provided».
Плагин dependencyИмея приведенную выше таблицу правил переноса scope и набор соответствующих артефактам файлов pom можно построить дерево зависимостей для каждой из фаз жизненного цикла проекта. Строить вручную долго и сложно. Можно использовать maven-плагин dependency и выполнить команду «mvn dependency:list», в результате выполнения которой получим итоговый список артефактов и их scope : F:\Projects\example>mvn dependency:list Scanning for projects... ------------------------------------------------------------------- Building example 2.1 ------------------------------------------------------------------- --- maven-dependency-plugin:2.8:list (default-cli) @ example --- The following files have been resolved: net.sf.ezmorph:ezmorph:jar:1.0.6:compile ru.test:dao:jar:2.11:compile net.sf.json-lib:json-lib:jar:jdk15:2.4:compile ru.test:iplugin:jar:1.1:compile commons-collections:commons-collections:jar:3.2.1:compile commons-beanutils:commons-beanutils:jar:1.8.0:compile commons-lang:commons-lang:jar:2.5:compile org.eclipse.swt.win32.win32.x86:org.eclipse.swt.win32.win32.\ x86:jar:3.7.1.v3738:compile commons-logging:commons-logging:jar:1.1.1:compile Однако к такому списку могут возникнуть вопросы : откуда взялся тот или иной артефакт? Т.е. желательно показать транзитные зависимости. И вот, команда «mvn dependency:tree» позволяет сформировать такое дерево зависимостей : F:\Projects\example>mvn dependency:tree Scanning for projects... ------------------------------------------------------------------- Building example 2.1 ------------------------------------------------------------------- --- maven-dependency-plugin:2.8:tree (default-cli) @ example --- ru.test:example:jar:2.1 +- net.sf.json-lib:json-lib:jar:jdk15:2.4:compile | +- commons-beanutils:commons-beanutils:jar:1.8.0:compile | +- commons-collections:commons-collections:jar:3.2.1:compile | +- commons-lang:commons-lang:jar:2.5:compile | +- commons-logging:commons-logging:jar:1.1.1:compile | \- net.sf.ezmorph:ezmorph:jar:1.0.6:compile +- ru.test:iplugin:jar:1.1:compile | \- ru.test:dao:jar:2.11:compile \- org.eclipse.swt.win32.win32.x86:org.eclipse.swt.win32.win32.\ x86:jar:3.7.1.v3738:compile Плагин dependency содержит большое количество целей goal, к наиболее полезным из которых относятся :
Копирование зависимости в локальный репозиторийСледующий команда загрузит библиотеку JFreeChart (версия 1.0.19) в локальный репозиторий. mvn dependency:get -Dartifact=org.jfree:jfreechart:1.0.19:jar |