Java Dependency Management – Avoiding Version Conflicts

dependenciesjavapatterns-and-practicesproject-structureversioning

Any Java project that uses my jar, will almost certainly have an additional dependency on another jar, which my jar also contains as a dependancy.

Problem is, that other jar has multiple versions.

How can I avoid any issues that might arise, in the likely case that your project's version of the 2nd jar is different from my jar's version of the 2nd jar?

I don't want my users to have the extra hassle of doing some fancy classloading trick in order to add my jar.

Should I just make a bunch of different versions of my jar, for every possible version of that common dependency? And then you just choose the version of my jar that uses the same whatever version of the 2nd jar you happen to have already?

Is there a smarter way to handle this, and make it easier for people to use my jar without conflicts?

Best Answer

It's not your problem. It is up to your end user to resolve. It just comes with the territory of using third-party dependencies, and I've had to resolve dependency conflicts more times than I count. You can't expect to accommodate every project's specific dependency conflicts.

Your software should operate correctly with the latest versions of your dependencies. Unless the dependency is changing their interface on every release, you should have a range of compatibility (e.g. your software works for all versions of dep in range [2.0.0, 3.0.0)). As long as you're maintaining the software, you should try to keep it compatible with the latest version of all your dependencies.

That said, here are some things I would find useful as a developer using your software with my different version of your dependency.

  • If the integration between your project and another project is tight, it's helpful to have a compatibility chart in your documentation. Regardless, you should mention any known issues with specific versions of the dependency in your documentation. Otherwise developers must find a compatible version by trial and error.
  • Abstract the collaboration with the dependency via an interface, and design your software so the implementation can be substituted with dependency injection. That allows me as the end user to substitute my own integration with version x of the library without bothering you.
  • Have a public issue tracker so your users can ask you to support certain versions of the common dependency. If you find many users want support for an incompatible version of the dependency, you can publish versions for both. See this Maven example where they target multiple platforms--support for different versions of a dependency should be similar.