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