Как исключить зависимость из родительского проекта в Maven? - PullRequest
28 голосов
/ 26 октября 2011

Например, у меня есть 2 проекта Maven. Одним из них является «проект-родитель». Другой - «проект-ребенок». Очевидно, «проект-ребенок» является подпроектом «проект-родитель».

«проект-родитель» имеет зависимость log4j. Но я хочу исключить это из «проекта-ребенка». Есть ли способ?

Вы можете сказать, что я должен переместить log4j из "project-parent" в "project-child". Это совершенно правильно. Но предполагается, что я НЕ МОГУ изменить POM "project-parent".

Заранее спасибо.

Ответы [ 5 ]

13 голосов
/ 26 октября 2011

Я не знаю, как на самом деле исключить зависимость, но вы можете исключить ее из целевого дистрибутива, но это что-то вроде хака. Вам нужно изменить область зависимости на то, что вы можете исключить в окончательном выпуске.

Итак, скажем, что у моего родителя была зависимость от junit 4.8, в моей помете вы говорите:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.8</version>
    <scope>provided</scope>
</dependency>

Итак, мы меняем область действия на предоставленную. Для объяснения того, как это работает, смотрите мой ответ на NoClassDefFoundError: org / junit / AfterClass во время обработки аннотации . К сожалению, это не влияет на сборку, но когда вы копируете зависимости для окончательного выпуска, вы можете использовать элемент конфигурации excludeScope, чтобы не копировать зависимость в окончательный выпуск:

<plugin>
<artifactId>maven-dependency-plugin</artifactId>

<executions>
    <execution>
        <id>copy-libs</id>
        <phase>package</phase>
        <goals>
            <goal>copy-dependencies</goal>
        </goals>
        <configuration>
            <outputDirectory>${project.build.directory}/lib</outputDirectory>
            <excludeScope>provided</excludeScope>
        </configuration>
    </execution>
11 голосов
/ 26 октября 2011

Я думаю, что в Maven2 нет способа достичь этого, потому что для этого и есть наследование POM.Однако есть одна хитрость, о которой я могу подумать:

Предположим, у вас есть право загружать артефакт в ваше внутреннее хранилище артефактов.Вы можете создать пустой JAR, развернуть его как log4j: log4j с явно ненормальной версией (например, log4j: log4j: 9999).Добавьте такую ​​зависимость в ваш проект-ребенка.Затем он переопределит зависимость родительского элемента от зависимой от фактически пустой JAR.

1 голос
/ 19 апреля 2017

Я встречал такой же вопрос, как и вы. В моем проекте позвольте вызвать родительский pom это parent.pom. родитель определил log4j, slf4j так:

       <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j-api.version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j-api.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j-log4j12.version}</version>
        </dependency>

дочерний проект вызывает некоторую зависимость в child.pom. Но я не хочу зависимости log4j-1.2.x и хочу увеличить версию slf4j.

Итак. Я добавляю зависимость родителя

<dependency>
        <groupId>parent</groupId>
        <artifactId>myartifactId</artifactId>
        <version>${my parent version}</version>
</dependency>

и используйте exclusion для удаления log4j

<dependency>
        <groupId>parent</groupId>
        <artifactId>myartifactId</artifactId>
        <version>${my parent version}</version>
        <exclusions>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
            </exclusion>
        </exclusions>
</dependency>

и явным образом добавьте зависимость slf4j и log4j2 в дочерний pom

 <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.6</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>

    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.3.4</version>
    </dependency>

затем используйте mvn dependency: tree , чтобы показать список зависимостей, все еще смотрите log4j

[INFO] +- org.apache.kafka:kafka_2.10:jar:0.8.2.0:compile
[INFO] |  +- com.yammer.metrics:metrics-core:jar:2.2.0:compile
[INFO] |  +- org.scala-lang:scala-library:jar:2.10.4:compile
[INFO] |  +- org.apache.zookeeper:zookeeper:jar:3.4.6:compile
[INFO] |  |  +- org.slf4j:slf4j-log4j12:jar:1.7.5:compile
[INFO] |  |  +- log4j:log4j:jar:1.2.17:compile

Хорошо, давайте добавим исключения для этой зависимости ... удалите этого парня.

    <dependency>
        <groupId>org.apache.kafka</groupId>
        <artifactId>kafka-clients</artifactId>
        <version>0.10.1.1</version>
        <exclusions>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

затем повторите команду, чтобы проверить список зависимостей. ХОРОШО! ясно ~

Надеюсь, что вам помогут:>

1 голос
/ 26 октября 2011

Если я понимаю вопрос, вам нужно что-то вроде следующего. Он получает зависимость и исключает ее из списка добавления. Часто это используется, если вы хотите внедрить более новую версию пакета вместо той, на которую ссылается другой пакет.

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.15</version>
    <exclusions>
        <exclusion>
            <groupId>com.sun.jmx</groupId>
            <artifactId>jmxri</artifactId>
        </exclusion>
        ...
    </exclusions>
    ...

Если вы вместо этого говорите об отношениях <parent>, то я не уверен, что есть способ сделать это. Можете ли вы перейти с <parent> на <dependency>?

0 голосов
/ 25 марта 2016

Один хакерский способ сделать это - указать зависимость в project-child, но с областью действия 'test' (или любой доступной областью с самым легким весом). Это будет «скрывать» область, указанную в project-parent, так что она будет доступна только для тестирования кода и недоступна для не тестового кода как во время компиляции, так и во время выполнения.

Я столкнулся с этой ошибкой в ​​основном по ошибке. В моем случае у моего проекта-потомка был одноуровневый проект с зависимостью области компиляции, в то время как у проекта-родителя была указана та же самая зависимость (фактически унаследованная от деда) с "предоставленной" областью действия. Однако project-child был исполняемым файлом, который зависел от одноуровневого проекта, и поэтому NoClassDefFoundError генерировался во время выполнения из project-sibling, так как использовался путь к классу времени выполнения дочернего проекта, который не включал в себя «обеспеченную» зависимость. Я исправил это, переместив зависимость 'compile' из project-sibling в project-parent, чтобы 'compile' 'скрывал' 'условии'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...