Как создать артефакт JarJar с Maven, где использование артефакта не вызывает транзитивных зависимостей?

В настоящее время у меня есть библиотека тестирования Java, которая построена с помощью Maven и распространяется в виде jar-файла. Мой проект зависит от очень распространенной библиотеки (Objectweb ASM), и у меня возникли проблемы, когда более ранняя и несовместимая версия ASM уже находится в пути к классам. Таким образом, я начал использовать jarjar-maven-plugin для создания jar, переупаковывая ASM внутри, где он не может конфликтовать с другой версией ASM.

Это выполняется нормально, и моя библиотека может быть вставлена ​​как зависимость без проблем.

Однако, поскольку мой проект имеет зависимости области компиляции от ASM, всякий раз, когда клиентский проект добавляет мою библиотеку, все транзитивные зависимости также извлекаются. Таким образом, гипотетически, если они используют определенную версию ASM, и они также добавляют версию, от которой я зависит, к пути к классам, они имеют неопределенное поведение. Я хотел бы избежать этой ситуации и позволить клиентам зависеть от артефакта JarJar, не заставляя Maven разрушать транзитивные зависимости как излишне, так и потенциально опасно.

Как создать артефакт JarJar, от которого могут зависеть пользователи, не используя транзитивные зависимости?

3 ответа

Решение

Я нашел решение этой проблемы, отказавшись от jarjar-maven-plugin и вернувшись к maven-shade-plugin. Это позволяет переупаковывать классы в вашем собственном пространстве имен, устанавливать основной класс jar и, самое главное, переписывать сгенерированный pom, чтобы он не включал зависимости времени компиляции, которые теперь связаны.

Часть моего pom.xml, которая достигла этого:

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

            <shadedArtifactAttached>false</shadedArtifactAttached>
            <createDependencyReducedPom>true</createDependencyReducedPom>

            <relocations>
                <relocation>
                    <pattern>org.objectweb.asm</pattern>
                    <shadedPattern>${repackage.base}.org.objectweb.asm</shadedPattern>
                </relocation>
            </relocations>
            <transformers>
                <transformer
                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                    <mainClass>${package.base}.my.MainClass</mainClass>
                </transformer>
            </transformers>
        </configuration>
    </execution>
</executions>

Важными частями этой конфигурации являются:

  • shadedArtifactAttached что при значении false означает, что заштрихованная банка заменит основной артефакт, который обычно создается. По умолчанию это false, но на это стоит обратить внимание.
  • createDependencyReducedPom что при значении true означает, что при развертывании или установке затененного jar-файла, развернутый файл pom.xml не будет включать в себя зависимости области компиляции, которые были переупакованы в jar-файл.
  • relocation Эти элементы настраивают, как файлы в зависимостях переупаковываются в затененный jar. В приведенном выше примере любой класс, каноническое имя которого начинается с org.objectweb.asm будет перемещен в ${package.base}.org.objectweb.asmи, следовательно, при упаковке в банку будет иметь эквивалентный путь к файлу внутри банки.

С этой конфигурацией, когда мой проект развернут, когда клиенты объявляют зависимость области компиляции от моего проекта, он тянет только затененный jar, и нет транзитивных зависимостей.

Попробуйте вместо этого попробовать плагин maven-shade-plugin, который обеспечивает все виды точного контроля.

Возможно постановка <optional> Атрибут будет работать в вашем случае. Указывая что-то вроде следующего в pom вашей библиотеки тестирования Java.

  <dependencies>
    <dependency>
      <groupId>asm.group</groupId>
      <artifactId>asm</artifactId>
      <version>x.y</version>
      <optional>true</optional>
    </dependency>
    ...
  </dependencies>
Другие вопросы по тегам