Статьи

Как интегрировать коммерческие сторонние артефакты в ваш Maven Build

Согласно  недавнему опросу RebelLabs компании ZeroTurnaround , Maven по-прежнему является ведущей платформой сборки Java. По данным RebelLabs, текущая доля рынка:

  • Maven с 64%
  • Муравей + Плющ с 16,5%
  • Gradle с 11%

Тем не менее, в то же время, Maven часто критикуют за то, что он немного неясен и навязчив. По сравнению с призерами Ant и Gradle, Maven допускает лишь небольшую гибкость в отношении интерпретации и, следовательно, индивидуальной адаптации модели сборки. Или, как   сказал бы Тим Берглунд из Data Stax:

Но давайте расскажем анекдоты и посмотрим на реальную проблему:

Интеграция сторонних коммерческих артефактов

Не все сторонние артефакты, от которых вы хотели бы зависеть, доступны бесплатно в Maven Central. Примерами этого являются коммерческие драйверы JDBC или  коммерческие выпуски jOOQ . Существуют три способа интеграции таких артефактов в вашу сборку:

Быстро и грязно

Часто вам нужна коммерческая зависимость только для небольшого тестового проекта или демонстрации. Вы хотите быть  уверены,  что он работает, когда вы запускаете его, независимо от настроек вашего локального репозитория или сетевого подключения. Это хороший вариант использования для  <scope>system</scope>:

Например: JOOQ

<dependency>
  <groupId>org.jooq</groupId>
  <artifactId>jooq</artifactId>
  <version>${jooq.version}</version>
  <scope>system</scope>
  <systemPath>${basedir}/lib/jooq-${jooq.version}.jar</systemPath>
</dependency>

Например: Microsoft SQL JDBC

<dependency>
  <groupId>com.microsoft.sqlserver</groupId>
  <artifactId>sqljdbc4</artifactId>
  <version>3.0</version>
  <scope>system</scope>
  <systemPath>${basedir}/lib/sqljdbc4.jar</systemPath>
 
  <!-- Notice that we can still put "optional"
       on commercial JDBC driver dependencies -->
  <optional>true</optional>
</dependency>

Преимущества этого подхода

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

Недостатки этого подхода

Системные зависимости никогда не переходят по наследству. Если ваш модуль зависит от jOOQ таким образом, зависимости вашего модуля не будут видеть API jOOQ.

Подробности о  системных зависимостях можно увидеть в документации Maven . Ссылаясь на документацию:

Зависимости с системой областей видимости всегда доступны и не ищутся в репозитории. Они обычно используются, чтобы сообщить Maven о зависимостях, предоставляемых JDK или виртуальной машиной. Таким образом, системные зависимости особенно полезны для разрешения зависимостей от артефактов, которые теперь предоставляются JDK, но где они доступны как отдельные загрузки ранее. Типичным примером являются стандартные расширения JDBC или Служба аутентификации и авторизации Java (JAAS).

Немного более надежный

Подход, который может показаться более надежным, состоит в проверке зависимостей из вашей системы управления версиями, а затем «вручную» импортировать их в локальный репозиторий. Это сделает их доступными для вашей  локальной сборки. Следующие сценарии оболочки показывают, как вы можете импортировать, например, артефакты jOOQ в ваш локальный репозиторий

Пакет Windows

@echo off
set VERSION=3.4.4
 
if exist jOOQ-javadoc\jooq-%VERSION%-javadoc.jar (
  set JAVADOC_JOOQ=-Djavadoc=jOOQ-javadoc\jooq-%VERSION%-javadoc.jar
  set JAVADOC_JOOQ_META=-Djavadoc=jOOQ-javadoc\jooq-meta-%VERSION%-javadoc.jar
  set JAVADOC_JOOQ_CODEGEN=-Djavadoc=jOOQ-javadoc\jooq-codegen-%VERSION%-javadoc.jar
  set JAVADOC_JOOQ_CODEGEN_MAVEN=-Djavadoc=jOOQ-javadoc\jooq-codegen-maven-%VERSION%-javadoc.jar
  set JAVADOC_JOOQ_SCALA=-Djavadoc=jOOQ-javadoc\jooq-scala-%VERSION%-javadoc.jar
)
 
if exist jOOQ-src\jooq-%VERSION%-sources.jar (
  set SOURCES_JOOQ=-Dsources=jOOQ-src\jooq-%VERSION%-sources.jar
  set SOURCES_JOOQ_META=-Dsources=jOOQ-src\jooq-meta-%VERSION%-sources.jar
  set SOURCES_JOOQ_CODEGEN=-Dsources=jOOQ-src\jooq-codegen-%VERSION%-sources.jar
  set SOURCES_JOOQ_CODEGEN_MAVEN=-Dsources=jOOQ-src\jooq-codegen-maven-%VERSION%-sources.jar
  set SOURCES_JOOQ_SCALA=-Dsources=jOOQ-src\jooq-scala-%VERSION%-sources.jar
)
 
call mvn install:install-file -Dfile=jOOQ-pom\pom.xml                          -DgroupId=org.jooq -DartifactId=jooq-parent        -Dversion=%VERSION% -Dpackaging=pom
call mvn install:install-file -Dfile=jOOQ-lib\jooq-%VERSION%.jar               -DgroupId=org.jooq -DartifactId=jooq               -Dversion=%VERSION% -Dpackaging=jar %JAVADOC_JOOQ%               %SOURCES_JOOQ%              -DpomFile=jOOQ-pom\jooq\pom.xml
call mvn install:install-file -Dfile=jOOQ-lib\jooq-meta-%VERSION%.jar          -DgroupId=org.jooq -DartifactId=jooq-meta          -Dversion=%VERSION% -Dpackaging=jar %JAVADOC_JOOQ_META%          %SOURCES_JOOQ_META%         -DpomFile=jOOQ-pom\jooq-meta\pom.xml
call mvn install:install-file -Dfile=jOOQ-lib\jooq-codegen-%VERSION%.jar       -DgroupId=org.jooq -DartifactId=jooq-codegen       -Dversion=%VERSION% -Dpackaging=jar %JAVADOC_JOOQ_CODEGEN%       %SOURCES_JOOQ_CODEGEN%      -DpomFile=jOOQ-pom\jooq-codegen\pom.xml
call mvn install:install-file -Dfile=jOOQ-lib\jooq-codegen-maven-%VERSION%.jar -DgroupId=org.jooq -DartifactId=jooq-codegen-maven -Dversion=%VERSION% -Dpackaging=jar %JAVADOC_JOOQ_CODEGEN_MAVEN% %SOURCES_JOOQ_CODEGEN_META% -DpomFile=jOOQ-pom\jooq-codegen-maven\pom.xml
call mvn install:install-file -Dfile=jOOQ-lib\jooq-scala-%VERSION%.jar         -DgroupId=org.jooq -DartifactId=jooq-scala         -Dversion=%VERSION% -Dpackaging=jar %JAVADOC_JOOQ_SCALA%         %SOURCES_JOOQ_SCALA%        -DpomFile=jOOQ-pom\jooq-scala\pom.xml

Linux Shell

#!/bin/sh
VERSION=3.4.4
 
if [ -f jOOQ-javadoc/jooq-$VERSION-javadoc.jar ]; then
  JAVADOC_JOOQ=-Djavadoc=jOOQ-javadoc/jooq-$VERSION-javadoc.jar
  JAVADOC_JOOQ_META=-Djavadoc=jOOQ-javadoc/jooq-meta-$VERSION-javadoc.jar
  JAVADOC_JOOQ_CODEGEN=-Djavadoc=jOOQ-javadoc/jooq-codegen-$VERSION-javadoc.jar
  JAVADOC_JOOQ_CODEGEN_MAVEN=-Djavadoc=jOOQ-javadoc/jooq-codegen-maven-$VERSION-javadoc.jar
  JAVADOC_JOOQ_SCALA=-Djavadoc=jOOQ-javadoc/jooq-scala-$VERSION-javadoc.jar
fi
 
if [ -f jOOQ-src/jooq-$VERSION-sources.jar ]; then
  SOURCES_JOOQ=-Dsources=jOOQ-src/jooq-$VERSION-sources.jar
  SOURCES_JOOQ_META=-Dsources=jOOQ-src/jooq-meta-$VERSION-sources.jar
  SOURCES_JOOQ_CODEGEN=-Dsources=jOOQ-src/jooq-codegen-$VERSION-sources.jar
  SOURCES_JOOQ_CODEGEN_MAVEN=-Dsources=jOOQ-src/jooq-codegen-maven-$VERSION-sources.jar
  SOURCES_JOOQ_SCALA=-Dsources=jOOQ-src/jooq-scala-$VERSION-sources.jar
fi
 
mvn install:install-file -Dfile=jOOQ-pom/pom.xml                         -DgroupId=org.jooq -DartifactId=jooq-parent        -Dversion=$VERSION -Dpackaging=pom
mvn install:install-file -Dfile=jOOQ-lib/jooq-$VERSION.jar               -DgroupId=org.jooq -DartifactId=jooq               -Dversion=$VERSION -Dpackaging=jar $JAVADOC_JOOQ               $SOURCES_JOOQ              -DpomFile=jOOQ-pom/jooq/pom.xml
mvn install:install-file -Dfile=jOOQ-lib/jooq-meta-$VERSION.jar          -DgroupId=org.jooq -DartifactId=jooq-meta          -Dversion=$VERSION -Dpackaging=jar $JAVADOC_JOOQ_META          $SOURCES_JOOQ_META         -DpomFile=jOOQ-pom/jooq-meta/pom.xml
mvn install:install-file -Dfile=jOOQ-lib/jooq-codegen-$VERSION.jar       -DgroupId=org.jooq -DartifactId=jooq-codegen       -Dversion=$VERSION -Dpackaging=jar $JAVADOC_JOOQ_CODEGEN       $SOURCES_JOOQ_CODEGEN      -DpomFile=jOOQ-pom/jooq-codegen/pom.xml
mvn install:install-file -Dfile=jOOQ-lib/jooq-codegen-maven-$VERSION.jar -DgroupId=org.jooq -DartifactId=jooq-codegen-maven -Dversion=$VERSION -Dpackaging=jar $JAVADOC_JOOQ_CODEGEN_MAVEN $SOURCES_JOOQ_CODEGEN_META -DpomFile=jOOQ-pom/jooq-codegen-maven/pom.xml
mvn install:install-file -Dfile=jOOQ-lib/jooq-scala-$VERSION.jar         -DgroupId=org.jooq -DartifactId=jooq-scala         -Dversion=$VERSION -Dpackaging=jar $JAVADOC_JOOQ_SCALA         $SOURCES_JOOQ_SCALA        -DpomFile=jOOQ-pom/jooq-scala/pom.xml

Приведенные выше сценарии по существу проверяют, доступны ли какие-либо из Javadoc, Sources и / или двоичных файлов в дистрибутиве, а затем устанавливают:

  • Родитель pom.xml
  • Различные двоичные файлы артефактов, исходные коды, файлы javadocs и pom.xml

Преимущества этого подхода

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

<dependency>
  <groupId>org.jooq</groupId>
  <artifactId>jooq</artifactId>
  <version>${jooq.version}</version>
</dependency>
 
<dependency>
  <groupId>com.microsoft.sqlserver</groupId>
  <artifactId>sqljdbc4</artifactId>
  <version>3.0</version>
  <scope>provided</scope>
</dependency>

Недостатки этого подхода

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

Путь

Очевидно, что при реальной настройке проекта ни один из вышеперечисленных подходов не будет достаточным, и вы, вероятно, импортируете библиотеки в свой локальный Nexus или Bintray или в любой используемый вами репозиторий. Просто остерегайтесь потенциальных ограничений на распространение, которые могут иметь коммерческие результаты.

Небольшое руководство по установке артефактов в Nexus можно найти здесь .