Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving transitive dependency conflicts in Java

I am trying to build a Dropwizard (Jersey) REST endpoint that communicates with HBase. Although these are my only two top-level dependencies, both of these dependencies come loaded with many transitive dependencies that conflict. A simple example of such a conflict is Google's Guava:

  • The HBase client specifies version 11
  • Dropwizard specifies 18

Dropwizard will not work with version 11 and HBase will not work with version 18.

I have examined the Maven shade plugin documentation, but it does not seem to let you relocate classes found in dependency jars. So I don't know how to resolve this issue short of separating these two components into separate JVMs.

like image 200
Dmitry Minkovsky Avatar asked Jun 10 '15 22:06

Dmitry Minkovsky


Video Answer


1 Answers

This is a dirty solution. But you could...

Create a project / module where you define a set of service interfaces that your dropwizard app will use to talk to HBase.

Create another module / project that implements these interfaces and uses the HBase classes. Shade this project.

In your Dropwizard project include only the interface jar but create a task to copy the shaded artifact into your resources.

Create a JARClassLoader for your shaded HBase client artifact. You may have to make a special subclass that does not delegate to the parent as by default the classloader will ask the parent to resolve linkages and may pull the newer version of guava from outer classloader.

Ask for an instance of the service contract from the Jar loader...

Businessing api = Class.forName("com.awesome.Businessing", true, jarLoader).newInstance();

like image 151
Steve Skrla Avatar answered Nov 01 '22 19:11

Steve Skrla