Затененная банка Maven, используемая в качестве внешней зависимости проекта

Я использовал плагин maven shadow в своем проекте, чтобы переместить все классы jar зависимостей в один пакет, например, org.shade.*

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

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


person erdarun    schedule 02.09.2016    source источник
comment
Вы путаете артефакт maven и результат процесса создания этого артефакта (банку или затененную банку). Добавление артефакта в качестве зависимости к проекту - это не просто загрузка файла jar, он будет анализировать pom зависимости, включать транзитивные зависимости, в конечном итоге также добавлять источники или тестировать jar в зависимости от pom xml,...   -  person Alexandre Cartapanis    schedule 02.09.2016
comment
Покажите нам, как вы включаете свою общую банку.   -  person Alexandre Cartapanis    schedule 02.09.2016


Ответы (2)


Классический сценарий:

  • Проект, создающий uber-jar, имеет свои собственные зависимости (элементы dependency в его pom.xml файле), которые затем упаковываются вместе в один uber-jar как артефакт Maven.
  • При использовании этого uber-jar в качестве зависимости (элемента dependency) другого проекта Maven затем проверяет его файл <artifact>-<version>.pom (опубликованный вместе с окончательным артефактом в репозитории Maven), который по сути является переименованной копией исходного файла pom.xml, где были объявлены зависимости (элемент dependency) (именно зависимости, упакованные в uber-jar).
  • Поскольку они уже упакованы, вы хотели бы игнорировать файл .pom (и его элемент dependencies), для этого вам нужно добавить exclusions следующим образом:

    <dependency>
        <groupId>com.sample</groupId>
        <artifactId>something-uber</artifactId>
        <version>some-version</version>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

Примечание: описанная выше функция доступна только с Maven 3.2.1.

Таким образом, вы даете понять Maven, что вам не нужна транзитивная зависимость и Посредничество зависимостей Maven не будет их запускать.


В качестве примечания: не рекомендуется иметь uber-jar в качестве зависимости от проекта: это просто усложнит обслуживание, поскольку вы не можете контролировать транзитивные зависимости через dependencyManagement или dependencies порядок зависимого проекта. Таким образом, вам всегда нужно будет переупаковывать uber jar всякий раз, когда зависимость (одна из ее транзитивных) будет нуждаться в обслуживании (изменение версии и т. д.) и иметь гораздо меньший контроль над зависимым проектом (опять же, более сложное обслуживание).

person A_Di-Matteo    schedule 02.09.2016


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

Я делюсь решением, которое позволяет вам избежать явного исключения всех транзитивных зависимостей, включая их в внешний проект, как объяснил @A_DiMatteo в своем решении (я также согласен с ним, чтобы избежать использования uber jar в качестве зависимости если по какой-то причине это не является строго необходимым). В результате вы сможете включить свою зависимость uber jar без использования элемента exclusions следующим образом:

<dependency>
  <groupId>com.sample</groupId>
  <artifactId>something-uber</artifactId>
  <version>some-version</version>
</dependency>

Предпосылка: моя цель состояла в том, чтобы предоставить как uber (без транзитивной зависимости, объявленной для pom), так и thin jar-файлы в моем репозитории. Итак, мое решение «А» основано на этом сценарии и в настоящее время имеет ограничение на то, что затененная банка загружается в репозиторий 2 раза.

  • Чтобы предоставить только банку uber, см. решение "B" ниже.
  • Возможное решение для ограничения "A" см. в разделе ОБНОВЛЕНИЕ в конце.

A) Предоставьте в репозитории как тонкие, так и убер-банки

1- В вашем исходном проекте настройте в модуле something pom.xml следующий maven-shade-plugin как следить:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.2</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <finalName>something-uber-${project.version}</finalName>
      </configuration>
    </execution>
  </executions>
</plugin>

Затем используйте плагин build-helper-maven-plugin, чтобы прикрепить новый артефакт с классификатором «uber» к модулю:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.2</version>
  <executions>
    <execution>
      <id>attach-artifacts</id>
      <phase>package</phase>
      <goals>
        <goal>attach-artifact</goal>
      </goals>
      <configuration>
        <artifacts>
          <artifact>
            <file>
              ${project.build.directory}/something-uber-${project.version}.jar
            </file>
            <classifier>uber</classifier>
          </artifact>
        </artifacts>
      </configuration>
    </execution>
  </executions>
</plugin>

В результате этапа установки maven будут сгенерированы следующие два файла jar в каталоге target/:

40K something-0.1.0.jar
7M  something-uber-0.1.0.jar

ВНИМАНИЕ: Выполнение затем этапа развертывания maven оба файла jar будут загружены в репозиторий! Цель здесь должна состоять в том, чтобы загрузить только тонкий файл jar, пропустив развертывание для затененной банки, чтобы оставить ее как локальный артефакт (возможное исправление см. в разделе ОБНОВЛЕНИЕ в конце)

2- Затем создайте еще один модуль в вашем исходном проекте с именем something-uber, добавив следующие зависимости и плагин:

<dependencies>
    <dependency>
        <groupId>com.sample</groupId>
        <artifactId>something</artifactId>
        <version>${project.version}</version>
        <classifier>uber</classifier>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.2</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Обратите внимание на следующее при включении зависимости:

  • классификатор должен быть равен uber (тот, который вы указали при присоединении нового артефакта с помощью build-helper-maven-plugin в первом модуле)
  • указаны исключения.

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

<dependency>
 <groupId>com.sample</groupId>
 <artifactId>something-uber</artifactId>
 <version>0.1.0</version>
</dependency>

B) Предоставить только uber jar в репозиторий

Начиная с решения «A», если вы хотите избежать предоставления thin jar в репозитории, вам следует избегать в пункте 1 указания finalName в конфигурации maven-shade-plugin и т. д. избегайте также плагина build-helper-maven-plugin, так как нет нового артефакта для подключения. Сделав это, развернув модуль, у вас будет только uber jar на цели/по умолчанию (без классификатора):

7M  something-0.1.0.jar

Вы также должны пропустить загрузку, иначе у вас также будут загружены две толстые банки ( something-0.1.0.jar & something-uber-0.1.0.jar ) . Для этого добавьте следующий плагин в тот же модуль:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-deploy-plugin</artifactId>
    <version>2.8.2</version>
    <configuration>
        <skip>true</skip>
    </configuration>
</plugin>

В конце пункта 2 просто не указывайте классификатор при добавлении зависимости следующим образом:

<dependencies>
 <dependency>
    <groupId>com.sample</groupId>
    <artifactId>something</artifactId>
    <version>${project.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>*</artifactId>
            <groupId>*</groupId>
        </exclusion>
    </exclusions>
 </dependency>
</dependencies>

ОБНОВЛЕНИЕ: пропустить загрузку первой затененной банки в решении A)

После некоторого безуспешного поиска решения я решил разветвить плагин maven-deploy-plugin из GitHub и работать над новой функцией, чтобы пропустить затененную банку, созданную в первом модуле, добавив настроенный плагин. следующим образом:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-deploy-plugin</artifactId>
  <version>3.0.0-SNAPSHOT</version>
  <configuration>
    <skipAttachedArtifacts>
      <artifact>
        <groupId>com.sample</groupId>
        <artifactId>something</artifactId>
        <version>${project.version}</version>
        <packaging>jar</packaging>
        <classifier>uber</classifier>
      </artifact>
    </skipAttachedArtifacts>
  </configuration>
</plugin>

В настоящее время при использовании подключаемого модуля maven-deploy-plugin все артефакты исключаются из развертывания, в то время как целью здесь является исключение только определенного. В моем форке я ввел параметр конфигурации «skipAttachedArtifacts», чтобы указать прикрепленные артефакты, которые следует исключить из развертывания.

Вот ссылка на мой разветвленный проект на GitHub: https://github.com/gregorycallea/maven-deploy-plugin

Вот ссылка на запрос на вытягивание, который я отправил в проекте плагина apache: https://github.com/apache/maven-deploy-plugin/pull/3

person gregorycallea    schedule 20.07.2018