Установите локальную зависимость jar как часть жизненного цикла, прежде чем Maven попытается ее разрешить

Из-за некоторой несовместимости между двумя зависимостями я был вынужден сделать затененную версию одной из моих зависимостей. Это значит, что мой проект теперь зависит от локального файла .jar.

Я раньше был совершенно прав, просто используя mvn install-file, чтобы установить этот .jar в мой локальный репозиторий, перед запуском mvn install:

mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=lib/my-custom-jar-1.0.0.jar
mvn install

Однако мой проект теперь будет на автоматическом сервере сборки, который будет делать только mvn clean install и ничего больше.

В поисках долгого времени я нашел несколько решений, но ни один из них не идеален.

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

Ответ 1

Вот несколько решений, которые я пробовал, но не очень хороши для моих целей:

1. Maven-установки-плагин

Идея состоит в том, чтобы добавить цель установочного файла как часть жизненного цикла установки, добавив это в pom:

<plugin>
  <artifactId>maven-install-plugin</artifactId>
  <version>2.5.2</version>
  <executions>
    <execution>
      <phase>validate</phase>
      <goals>
        <goal>install-file</goal>
      </goals>
      <configuration>
        <file>lib/my-custom-jar-1.0.0.jar</file>
      </configuration>
    </execution>
  </executions>
</plugin>

[...]

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
</dependency>

Однако даже при самой первой цели validate Maven будет пытаться разрешить зависимости до запуска файла install.

Я видел идею использования чистой цели. Раздражающе, это работает, когда вы выполняете отдельные команды (mvn clean && mvn install), но если вы выполняете оба действия в одной команде mvn (mvn clean install), Maven сначала разрешит зависимости. Может ли быть решение этого?

2. Проект с несколькими модулями

Идея увиденная в этом ответе на переполнение стека, заключается в том, что вы устанавливаете файл в родительском pom и добавляете зависимость в дочернем помпе. Maven будет разрешать отдельные зависимости отдельно, поэтому это должно работать.

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

3. Область системы с основанием

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
  <scope>system</scope>
  <systemPath>${basedir}/lib/my-custom-jar-1.0.0.jar</systemPath>
</dependency>

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

4. addjars-Maven-плагин

Этот настраиваемый плагин, найденный здесь, включает в себя .jar в вашем .war файле, а затем добавляет его вашему pom во время компиляции.

<plugin>
  <groupId>com.googlecode.addjars-maven-plugin</groupId>
  <artifactId>addjars-maven-plugin</artifactId>
  <version>1.0.5</version>
  <executions>
    <execution>
      <goals>
        <goal>add-jars</goal>
      </goals>
      <configuration>
        <resources>
          <resource>
            <directory>${basedir}/lib</directory>
            <includes>
              <include>**/my-custom-jar-1.0.0.jar</include>
            </includes>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

Это будет работать в большинстве обычных случаев. Однако, поскольку вы не указали какую-либо зависимость от вашего пользовательского .jar в вашем фактическом pom, в вашей среде IDE будет отсутствовать много классов, поэтому вам нужно вручную добавить свой пользовательский .jar в качестве внешней библиотеки.

Это все еще несколько взломанно и не работает с некоторыми специальными случаями (hpi: run для отладки Jenkins, например, вызывает некоторые ошибки). Плюс я предпочел, чтобы мой код не полагался на сторонние плагины.

5. Входящий в каталог репозиторий Maven

Я нашел это решение после создания этого сообщения, и я очень доволен им.

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

Вам необходимо предварительно установить библиотеку с помощью этой команды.

mvn org.apache.maven.plugins:maven-install-plugin:2.5.1:install-file \
-Dfile=lib/cloudfoundry-client-lib-shaded-1.0.3.jar \
-DlocalRepositoryPath=lib

После этого ваш репозиторий будет создан в папке lib, и вам больше не понадобится выполнять эту команду.

Укажите, что вы хотите использовать этот репозиторий в своей папке:

<repository>
  <id>Local repository</id>
  <url>file://${basedir}/lib</url>
</repository>

[...]

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
</dependency>

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

Ответ 2

Выполняет выполнение тени в одном подпроекте (называет его S), он ест версию (а) зависимости вашей проблемы и создает свой собственный результат G/A/V'd. Настройте оттенок для получения основного вывода подпроекта. Другими словами, S производит группу: артефакт: версия, полностью отличная от координат вещи, с которой вы начинаете, из которой вам нужны две версии.

В ваших других подпроектах просто объявите (S) как зависимость для получения заштрихованной версии, а затем вы также можете объявить незашифрованную другую версию.

Все это предполагает, что вы переименовали пакеты при затенении.

Нет необходимости устанавливать: ничего.