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. То же, что и все классы, упомянутые в предупреждениях.
Одна вещь, которую нужно упомянуть, это то, что я использую теневой плагин в моем 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 пытается сжать их до большой толстой банки в конце. затем появляется предупреждение. Было сказано, что это невежественное предупреждение. Но я немного волнуюсь. Как приложение знает, какой именно класс следует использовать, если есть два дублированных класса с тем же именем?
Ответы
Ответ 1
Взгляните на раздел "Исключения зависимостей" в Maven doc.
В приведенном примере я исключу зависимость 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>
Ответ 2
Возможно, вы также столкнулись с ограничением maven-shader-plugin. Он заменяет артефакт jar по умолчанию (созданный maven-jar-plugin). Это отлично работает на чистой сборке, но при восстановлении, где банка не восстанавливается, шейдер снова запускается на банке, созданной в последний раз, которая уже содержит копии всех зависимостей классов. Это вызывает много предупреждений о дубликатах.
Эта проблема по-прежнему не затрагивается как из maven-shader-plugin 2.0: http://jira.codehaus.org/browse/MSHADE-126
Один способ заключается в том, чтобы добавить maven-jar-plugin явным образом в ваш pom.xml и добавить настройку конфигурации <forceCreation>true</forceCreation>
.
Ответ 3
В моем случае мой родительский pom был в том числе commons-beanutils, а мой дочерний модуль (который я хотел только скомпилировать) включал commons-io.
Штепсельная вилка жаловалась на дубликаты, так как commons-io и commons-beansutil разделяли некоторые общие классы. Обратите внимание, что beansutiul был включен, хотя он не был нужен и не использовался.
Я решаю это, сводя к минимуму банку, добавив это в конфигурацию:
<minimizeJar>true</minimizeJar>
Теперь теневой плагин не добавил неиспользуемые ресурсы.
Предупреждение исчезло.
Ответ 4
Вы можете исключить банку, которую вы не хотите (те, которые предоставляют дублирующиеся предупреждения, используя следующие теги под плагином оттенков -
<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
Ответ 5
У вас есть зависимости в вашем pom, которые содержат повторяющиеся классы, но без соответствующего pom я не мог сказать ни слова об этом.
Ответ 6
Я видел, как это происходило в eclipse, когда я обновлял зависимости родительского проекта.
Я удалил все файлы в моем целевом каталоге и исправил проблемы.
Ответ 7
Все выше (о просмотре дерева зависимостей и исключении) в большинстве случаев является правильным, но в моем случае (у меня не было перекрытия в моих зависимостях), предварительный clean
помог (не знаю почему):
mvn clean package