Miguel Miguel - 5 months ago 13
Java Question

Is there anyway to exclude artifacts inherited from a parent POM?

Artifacts from dependencies can be excluded by declaring an

<exclusions>
element inside a
<dependency>
But in this case it's needed to exclude an artifact inherited from a parent project. An excerpt of the POM under discussion follows:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>jruby</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<artifactId>base</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
</parent>

<dependencies>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>ALL-DEPS</artifactId>
<version>1.0</version>
<scope>provided</scope>
<type>pom</type>
</dependency>
</dependencies>
</project>


base
artifact, depends on
javax.mail:mail-1.4.jar
, and
ALL-DEPS
depends on another version of the same library. Due to the fact that
mail.jar
from
ALL-DEPS
exist on the execution environment, although not exported, collides with the
mail.jar
that exists on the parent, which is scoped as
compile
.

A solution could be to rid off mail.jar from the parent POM, but most of the projects that inherit base, need it (as is a transtive dependency for log4j). So What I would like to do is to simply exclude parent's library from the child project, as it could be done if
base
was a dependency and not the parent pom:

...
<dependency>
<artifactId>base</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
<type>pom<type>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
</exclusions>
</dependency>
...

Answer

Some ideas:

  1. Maybe you could simply not inherit from the parent in that case (and declare a dependency on base with the exclusion). Not handy if you have lot of stuff in the parent pom.

  2. Another thing to test would be to declare the mail artifact with the version required by ALL-DEPS under the dependencyManagement in the parent pom to force the convergence (although I'm not sure this will solve the scoping problem).

    <dependencyManagement>
      <dependencies>
        <dependency>    
          <groupId>javax.mail</groupId>
          <artifactId>mail</artifactId>
          <version>???</version><!-- put the "right" version here -->
        </dependency>
      </dependencies>
    </dependencyManagement>
    
  3. Or you could exclude the mail dependency from log4j if you're not using the features relying on it (and this is what I would do):

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.15</version>
      <scope>provided</scope>
      <exclusions>
        <exclusion>
          <groupId>javax.mail</groupId>
          <artifactId>mail</artifactId>
        </exclusion>
        <exclusion>
          <groupId>javax.jms</groupId>
          <artifactId>jms</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.sun.jdmk</groupId>
          <artifactId>jmxtools</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.sun.jmx</groupId>
          <artifactId>jmxri</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    
  4. Or you could revert to the version 1.2.14 of log4j instead of the heretic 1.2.15 version (why didn't they mark the above dependencies as optional?!).