David
David

Reputation: 1458

Can I overwrite a maven dependency version through my local repository?

I have a bit of a dependency hell situation here that I'm trying to resolve: I have three projects, A, B and C. A and B both depend on C. Now A is my own module that I have direct control over, B is a library I'm using, C is a library that is used both directly from my module A and by my dependency B.

To visualize this:

   C
   ^
 /  B
|   ^
 \ /
  A

For various reasons I now needed to make a small change to C that I need locally but don't want to (or can't) deploy to the global repository from which C is downloaded normally.

I tried to do this by tagging my modified version of C installed in my local repository with a classifier and changing the dependency to it in A's POM to include the classifier like this:

<dependency>
  <groupId>foo</groupId>
  <artifactId>C</artifactId>
  <version>0.7.16</version>
  <classifier>myclassifier</classifier>
</dependency>

But mvn dependency:tree now shows that I have both the version with the classifier and the version without it in my classpath because of the transitive dependency:

[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ A ---
[INFO] org.example:A:jar:0.1-SNAPSHOT
...
[INFO] +- foo:C:jar:myclassifier:0.7.16:compile
[INFO] +- bar:B:jar:3.2.5:compile
[INFO] |  +- foo:C:jar:0.7.16:compile

Is there any way I can force my project / maven to just use my modified version in this context?

Edit: Solution

For now, I've solved it using exclusions like this in A's pom.xml thanks to the answers by Filipe and Samuel.

<dependency>
  <groupId>foo</groupId>
  <artifactId>C</artifactId>
  <version>0.7.16</version>
  <classifier>myclassifier</classifier>
</dependency>

<dependency>
  <groupId>bar</groupId>
  <artifactId>B</artifactId>
  <version>3.2.5</version>
  <exclusions>
    <exclusion>
      <groupId>foo</groupId>
      <artifactId>C</artifactId>
    </exclusion>
  <exclusions>
</dependency>

Note: This of course only works as long as the edits in C are really minor and don't change the API used by B, which for me is the case.

Upvotes: 0

Views: 816

Answers (2)

Samuel EUSTACHI
Samuel EUSTACHI

Reputation: 3156

Obviously this new version of C is for you not a new artifact, but a new version of this artifact.

So you should not use here a classifier but a version number increase instead.

Your project will be built with the last version (and even if you have a problem to resolve the last version, you can exclude the transitive dependency in your pom)

However, you must be very carefull when doing this, because your B project will have been compiled with the old version of C. So if you modify method erasure, or remove methods or classes, you will have runtime trouble.

If you only add classes or methods in your C library, then it should work.

Upvotes: 2

Filipe Fedalto
Filipe Fedalto

Reputation: 2540

You're saying that C is the official version of the library and that your minor change (Let's call it C2) would only be used by A. You're also saying that by declaring in A the direct dependency on C2, than it's unfortunately expected that you end up with C2 and C. C will be a transitive dependency from B. Unfortunately too, the Maven reactor treats libraries with the same version but with a different classifier as different libraries, giving you exactly this result (of having both C and C2).

If you only need C2 in project A, you could explicitly add exclusions to C into A's POM.

Upvotes: 2

Related Questions