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.
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();