Carol
Carol

Reputation: 71

Maven: how to override dependency

My situation is a bit strange:

Dependency with artifact id: yyy in the pom (see below) has dependency:

<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>2.5</version>
</dependency>

So the problem is I need to use the 3.1.0 version in the current module because it has extra functionality:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>

I have tried the exclusions tag and dependencymanagement tag explained in the example on the page: Maven: how to override the dependency added by a library

It does not work. I have also read and tried the 3 examples in this article: https://spring.io/blog/2016/04/13/overriding-dependency-versions-with-spring-boot

It also did not work. So what I did was to re-order my pom dependencies so that the 3.1.0 goes before the one with artifact yyy and I was happy it worked I built successfully a clean install. My happiness was short lived because after a clean install the pom re-ordered itself and the 3.1.0 was automatically re-ordered back below the yyy. Which means the next build will use 2.5 again and fail.

My pom structure snippet is as below:

<dependencies>
  <dependency>
    <groupId>xxxx.xxx.xxxx</groupId>
    <artifactId>yyy</artifactId>
    <version>1.0.0</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
  </dependency>
<dependencies>

Upvotes: 2

Views: 8990

Answers (2)

Carol
Carol

Reputation: 71

The solution below has ignored the version 2.5 and so it is working. However i don't know what it means. Does it remove other dependencies? Please interpret what the asterix in groupId and artifactId mean in simple english. I want to know the risks because i am using a multi module system where there to many nested dependencies in other dependencies. I will continue to research as of now but if anyone can explain please do. Thanks

    <dependencies> 
      <dependency>
         <groupId>xxxx.xxx.xxxx</groupId>
         <artifactId>yyy</artifactId>
         <version>1.0.0</version>
         <exclusions> 
            <exclusion> 
              <groupId>javax.servlet</groupId>  // this works or 
              <groupId>*</groupId> // this works
              <artifactId>*</artifactId> // this part was a mandatory *
            </exclusion> 
         </exclusions> 
      </dependency> 
      <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>javax.servlet-api</artifactId>
         <version>3.1.0</version>
      </dependency>
    </dependencies> 

Upvotes: 0

davidxxx
davidxxx

Reputation: 131326

My happiness was short lived because after a clean install the pom re-ordered itself and the 3.1.0 was automatically re-ordered back below the yyy. Which means the next build will use 2.5 again and fail.

Note that the javax.servlet:javax.servlet-api has to be included in a WAR but only in a standalone JAR that includes and bootstraps a servlet container.
If you build a standard WAR you have to use the dependency provided by the server. So the dependency should be declared with the provided scope.

I have tried the exclusions tag and dependencymanagement tag explained in the example on the page: Maven: how to override the dependency added by a library

dependencyManagement will be helpless here as the issue is related to a dependency you include outside the dependencyManagement element.
But using the exclusions option in the dependency declaration is the right way. It should exclude the 2.5 version of the javax.servlet-api artifact if used in this way :

<dependencies>
  <dependency>
    <groupId>xxxx.xxx.xxxx</groupId>
    <artifactId>yyy</artifactId>
    <version>1.0.0</version>
    <exclusions>
      <exclusion>
        <artifactId>javax.servlet</artifactId>
        <groupId>javax.servlet-api</groupId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
  </dependency>
</dependencies>

If the problem persists it means that the dependency is probably pulled by another dependency.
Some hints that generally help to discover that :

  • check that you don't use WAR overlay feature. But not likely here as you retrieve only 1 version of the dependency

  • use mvn dependency:tree on the WAR project to inspect all pulled dependencies.
    To ease the readable you can also filter in this way :
    mvn dependency:tree -Dincludes=javax.javax.servlet-api

Upvotes: 3

Related Questions