Maven build [ПРЕДУПРЕЖДЕНИЕ] у нас есть дубликат класса
Кто-нибудь знает, что случилось с моей сборкой Maven? Я получаю много повторяющихся предупреждений.
[WARNING] We have a duplicate org/apache/commons/logging/impl/LogFactoryImpl$1.class in /home/shengjie/.m2/repository/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar
[WARNING] We have a duplicate org/apache/commons/logging/impl/LogFactoryImpl.class in /home/shengjie/.m2/repository/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar
[WARNING] We have a duplicate org/apache/commons/logging/impl/NoOpLog.class in /home/shengjie/.m2/repository/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar
[WARNING] We have a duplicate org/apache/commons/logging/impl/SimpleLog$1.class in /home/shengjie/.m2/repository/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar
[WARNING] We have a duplicate org/apache/commons/logging/impl/SimpleLog.class in /home/shengjie/.m2/repository/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar
[WARNING] We have a duplicate org/apache/commons/logging/impl/Jdk14Logger.class in /home/shengjie/.m2/repository/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar
Я заглянул в свой локальный репозиторий m2, у меня есть два класса в commons-logging-api jar, LogFactoryImpl.class и LogFactoryImpl$1.class. То же, что и все классы, упомянутые в предупреждениях.
Стоит упомянуть, что я использую плагин Shade в моем pom.xml.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.~~~~black out my own main class here~~~~~</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Я заметил, что дерево зависимостей выглядит так, как показано ниже
[INFO] +- org.apache.cxf:cxf-bundle-jaxrs:jar:2.5.1:compile
[INFO] | \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] \- org.apache.hadoop.hive:hive-jdbc:jar:0.7.1-cdh3u3:compile
[INFO] \- org.apache.hadoop.hive:hive-common:jar:0.7.1-cdh3u3:compile
[INFO] \- commons-logging:commons-logging-api:jar:1.0.4:compile
и commons-logging.jar и commons-logging-api.jar оба имеют org/apache/commons/logging/LogFactory.class.
каким-то образом плагин Shad пытается сжать их в большую толстую банку в конце. тогда появляется предупреждение. Было сказано, что это игнорируемое предупреждение. Но я немного волнуюсь, откуда приложение знает, какой именно класс следует использовать, если есть два дублированных класса с одинаковыми именами?
8 ответов
Взгляните на раздел "Исключения зависимостей" в документе Maven.
В приведенном вами примере я исключу commons-logging:commons-logging-api:jar:1.0.4:compile
зависимость от org.apache.hadoop.hive:hive-common:jar:0.7.1-cdh3u3:compile
, В вашем pom.xml:
<dependency>
<groupId>org.apache.hadoop.hive</groupId>
<artifactId>hive-common:jar</artifactId>
<version>0.7.1-cdh3u3</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
</exclusion>
</exclusions>
</dependency>
Возможно, вы также столкнулись с ограничением maven-shader-plugin. Он заменяет артефакт jar по умолчанию (созданный maven-jar-plugin). Это отлично работает при чистой сборке, но при перекомпоновке, где jar не регенерируется, шейдер снова запускается на jar, который он создал в прошлый раз, который уже содержит копии всех зависимостей класса. Это производит много предупреждений о дубликатах.
Эта проблема до сих пор не решена, поскольку в maven-shader-plugin 2.0: https://issues.apache.org/jira/browse/MSHADE-126
Одним из обходных путей является явное добавление maven-jar-plugin в ваш файл pom.xml и добавление параметра конфигурации <forceCreation>true</forceCreation>
,
В моем случае мой родительский pom включал в себя commons-beanutils, а мой дочерний модуль (это единственное, что я хотел скомпилировать) включал commons-io.
Плагин shade жаловался на дубликаты, так как commons-io и commons-beansutil имеют несколько общих классов. Обратите внимание, что beansutiul был включен, хотя он не был нужен и не использовался.
Я решаю это путем минимизации фляги, добавляя это к конфигурации:
<minimizeJar>true</minimizeJar>
Теперь плагин Shade не добавляет неиспользуемые ресурсы.
Предупреждение ушло.
Все вышеизложенное (о просмотре дерева зависимостей и исключении) в большинстве случаев является правильным, но в моем случае (у меня не было перекрытия в моих зависимостях) предварительно clean
помог (хотя не знаю почему):
mvn clean package
Вы можете исключить банку, которая вам не нужна (те, которые выдают двойные предупреждения, используя следующие теги в плагине тени -
<configuration>
<artifactSet>
<excludes>
<exclude>commons-logging:commons-logging</exclude>
</excludes>
</artifactSet>
<minimizeJar>true</minimizeJar>
</configuration>
Более подробную информацию можно найти по http://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html
В моем случае я полагался на упаковку, которая также создает затененную банку.
Затененные банки предназначены для развертывания, а не для установки в качестве зависимости.
Создание сокращенного POM для зависимости во время процесса построения зависимости указывает maven, какие зависимости могут быть опущены.
В конфигурации maven-shade-plugin:
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
Для более подробной информации смотрите этот пост:
Для чего используется плагин maven-shade-plugin и почему вы хотите переместить java-пакеты?
Ошибка, которую я получал от Maven:
ВНИМАНИЕ: x.jar, y.jar содержат перекрывающиеся классы
Я видел, что это произошло в затмении, когда я обновил зависимости моего родительского проекта.
Я удалил все файлы в моей целевой директории, и это устранило проблемы.
У вас есть зависимости в вашем pom, которые содержат повторяющиеся классы, но без соответствующего pom я не мог бы сказать об этом ни слова.