How to exclude a dependency from parent's project in Maven?

I think in Maven2 there is no way to achieve this, because this is what POM inheritance is for . However there is one trick that I can think of:

Assume you have the right to upload artifact to your internal artifact repository. You may create an empty JAR, deploy it as log4j:log4j, with a obviously abnormal version (e.g. log4j:log4j:9999 ). Add such dependency in your project-child. Then it will override the dependency of parent to depends on a in-fact-empty JAR.


I don't know of a way of actually excluding a dependency, but you can exclude it from the target distribution, but it's a bit of a hack. You need to change the scope of the dependency to something that you can exclude in the final distribution.

So, say that my parent had a dependency on junit 4.8, in my pom you say:

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

So we're changing the scope to provided. For an explanation of how this works, see my answer to NoClassDefFoundError: org/junit/AfterClass during annotation processing. Unfortunately, this doesn't affect the build, but when you're copying the dependencies for the final distribution, you can use the excludeScope configuration element to not copy the dependency into the final distribution:

<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>

I have met the same question just like you. In my project, let call the parent pom is parent.pom. parent defined the log4j, slf4j like this:

       <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 project invoke some dependency in child.pom. But I don't want the log4j-1.2.x dependency and want to increase the version of slf4j.

So. I add the dependency of parent

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

and use exclusions to remove the log4j

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

and explicitly add the slf4j and log4j2's dependency in child 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>

then use mvn dependency:tree to show the dependency list, still see the 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

well, let's add the exclusions on that dependency...remove this guy.

    <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>

then run the command again to check the dependency list. OK! clear~

Hope that can help you :>

Tags:

Java

Maven