Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting Jersey 1.x and 2.x to coexist

I've got a Dropwizard project (using Jersey 2.x) where I need to use another library that has a dependency on jersey-client from 1.x and I'm having some trouble getting both to coexist on the classpath. It looks like what is happening is that HK2 is finding anything that implements providers from javax.ws.rs.* and attempting to instantiate them. When it's a class from Jersey 1.x, the dependency injection that it needs isn't there and I end up with lots of errors like:

Caused by: java.lang.IllegalArgumentException: The MultiPartConfig instance we expected is not present. Have you registered the MultiPartConfigProvider class?
  at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.<init>(MultiPartReaderClientSide.java:107)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
  at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1107)
  at org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:274)
  at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368)

Is there any way to get Jersey 2.x/HK2 to ignore anything in the com.sun.jersey.* package space?

like image 812
Will Gorman Avatar asked Apr 14 '15 16:04

Will Gorman


1 Answers

It looks like the default behavior for org.glassfish.jersey.internal.ServiceFinder is to find service implementations via META-INF/services on the classpath. However, it has a setIteratorProvider method that allows you to set an alternate ServiceIteratorProvider implementation. I was able solve the problem by giving it an implementation that filters out any class names from com.sun.jersey.*

public class Jersey2ServiceIteratorProvider extends ServiceFinder.ServiceIteratorProvider {

    ServiceFinder.DefaultServiceIteratorProvider delegate =  new ServiceFinder.DefaultServiceIteratorProvider();
    @Override
    public <T> Iterator<T> createIterator(Class<T> service, String serviceName,
                                          ClassLoader loader, boolean ignoreOnClassNotFound) {
        return delegate.createIterator(service, serviceName, loader, ignoreOnClassNotFound);
    }

    @Override
    public <T> Iterator<Class<T>> createClassIterator(Class<T> service, String serviceName,
                                                      ClassLoader loader, boolean ignoreOnClassNotFound) {
        final Iterator<Class<T>> delegateClassIterator = delegate.createClassIterator(service, serviceName, loader, ignoreOnClassNotFound);
        return Iterators.filter(delegateClassIterator, input -> !input.toString().startsWith("class com.sun.jersey"));
    }
}
like image 130
Will Gorman Avatar answered Sep 23 '22 04:09

Will Gorman