[GRADLE-646] Support custom version conflict strategies Created: 22/Sep/09  Updated: 10/Feb/17  Resolved: 10/Feb/17

Status: Resolved
Project: Gradle
Affects Version/s: 0.2, 0.3, 0.4, 0.5, 0.5.1, 0.5.2, 0.6, 0.6.1, 0.7, 0.8
Fix Version/s: None

Type: New Feature
Reporter: Jason Porter Assignee: Unassigned
Resolution: Won't Fix Votes: 8


All the user to create their own version conflict resolution strategies. Mailing list reference: http://www.nabble.com/Force-two-versions-of-a-jar--td25367885.html

Comment by Tamás Kozma [ 21/Sep/11 ]

From the user guide:

If you are familiar with Maven or Ivy approach you will be delighted to learn that:

  • All the concepts that you already know and like are still there and are fully supported by Gradle. [...]
  • Gradle works perfectly with your existent dependency management infrastructure, be it Maven or Ivy. [...] No changes necessary.


In your dependency description you tell Gradle which version of a dependency is needed by another dependency. This frequently leads to conflicts. Different dependencies rely on different versions of another dependency. [...] What Gradle offers you is a resolution strategy, by default the newest version is used.

Based on this, I believe everyone would assume Gradle has the same flexibility to deal with version conflicts as Ivy does. In any case, I had taken that for granted, only to find this is not the case after investing a lot of time into setting up a Gradle build environment at my company (for .NET projects, which in most aspects went fine this far). This means we cannot use Gradle as it is today, because we want to detect version conflicts early on.

I looked into the source code, and as far as I can tell, it would be very simple and straightforward to expose Ivy's default conflict resolver (and circular dependency resolver, if we are already at it) setting. I understand that you aim for something more advanced and Gradleish in the long run, but I believe letting users configure such default plugins is a very good first step, would not cross any further plans and would enable most scenarios.

What do you think? If I sent you a patch for this, would you consider it? Do you see any problems with such a simple approach? Just to reiterate: this is a dealbreaker for us, and as I have seen on forums and mail archives, for others as well.

Comment by Adam Murdoch [ 22/Sep/11 ]

It depends how you tackled it. We want to solve the use case, and I'd like to start with something simple which handles your use case, but which we can later incrementally improve.

I'd rather not use Ivy's ConflictManager interface on the public Gradle API, as we've just spent a good amount of effort moving away from Ivy's DependencyResolver. This is a dead end, as far as I'm concerned.

So, if we can get away with (for now) having a small set of hardcoded conflict managers which you can choose from, rather than some general capability to provide custom conflict management, I'd like to go with that. Ideally, we'd start with just 'use latest' and 'don't allow any conflicts' to choose from.

One question is where this setting belongs. To me, it belongs on Configuration, ie it's a setting that belongs with the other per-resolvable dependencies settings.

Comment by Tamás Kozma [ 23/Sep/11 ]

I'm sad to hear that you want to hide Ivy even more. For me, the biggest selling point of Gradle is its use of Ivy, a proven and flexible system that I like very much. If I were you I would embrace it instead, so that I could say with confidence that Gradle indeed knows everything that Ivy does, and more. But I guess this is not up for debate and I'm sure you have your reasons.

However, you saying that exposing Ivy is a dead end, confirms that we should not go with Gradle. It is that very customizability that Ivy offers that enables our use of Gradle. We wrote a custom Ivy resolver for our internal repository, we created an Ivy module descriptor parser for our descriptor format, we plugged in our own Ivy message logger, we would want to use a custom conflict resolver and version matcher to deal with our versioning scheme, and so on.

But to reply to you, I agree that some built in conflict resolution strategies would be sufficient for most. Besides the latest and the no-conflict strategy, a compatible strategy (for some notation, for example 1.2.+) is often used.

It might belong to a Configuration logically, but then again, I hardly see a case where you would use two different strategies for two configurations in the same build. It might simplify the build script if you only have a single universal resolution strategy. Also, if you assign it to configurations, you have to think about what should happen when a configuration extends another with a different strategy. I mean not just you, but the user too.

Comment by Szczepan Faber [ 01/Oct/11 ]

@Tamas, some recent development in master should make you happier I've added 2 basic conflict strategies. https://github.com/gradle/gradle/commit/7b9884158f28ce0126933588451c178fb869df31

There's going to be some polishing around the DSL, yet.

Comment by Tamás Kozma [ 03/Oct/11 ]

Way to go

Comment by Szczepan Faber [ 07/Nov/11 ]

First step in improving management of version conflicts: GRADLE-1899

Comment by Jacob Aleksynas [ 22/Mar/12 ]

I'd love to see one additional conflict manager... The "all" manager from Ivy.

The main use-case is an upgrade from one library to another.. jmock 1 to 2 or even Junit 3.X -> 4.X where BOTH jars can happily live on the classpath and allow for incremental migration of test cases

I have quite a bit of this in my codeline and have had a heck of a time working around it.

Comment by Szczepan Faber [ 02/Apr/12 ]

Thanks for feedback - very interesting (and legitimate) use case. How did you work around it? Separate configurations and changing the test.classpath property?

Comment by Jacob Aleksynas [ 25/Oct/12 ]

Yes, separate config and updating classpaths. This approach gets nasty with transitive dependencies and with extended configurations. so i could only use this approach effectively (read "cleanly") with the test use case above. With other runtime focused issues of this nature; I have to upgrade code and fix the necessity for "all" modules.

Comment by Benjamin Muschko [ 15/Nov/16 ]

As announced on the Gradle blog we are planning to completely migrate issues from JIRA to GitHub.

We intend to prioritize issues that are actionable and impactful while working more closely with the community. Many of our JIRA issues are inactionable or irrelevant. We would like to request your help to ensure we can appropriately prioritize JIRA issues you’ve contributed to.

Please confirm that you still advocate for your JIRA issue before December 10th, 2016 by:

  • Checking that your issues contain requisite context, impact, behaviors, and examples as described in our published guidelines.
  • Leave a comment on the JIRA issue or open a new GitHub issue confirming that the above is complete.

We look forward to collaborating with you more closely on GitHub. Thank you for your contribution to Gradle!

Comment by Benjamin Muschko [ 10/Feb/17 ]

Thanks again for reporting this issue. We haven't heard back from you after our inquiry from November 15th. We are closing this issue now. Please create an issue on GitHub if you still feel passionate about getting it resolved.

Generated at Wed Jun 30 11:35:15 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.