让泽西岛1.x和2.x共存

时间:2015-04-14 16:19:06

标签: java jersey jersey-2.0 dropwizard hk2

我有一个Dropwizard项目(使用Jersey 2.x),我需要使用另一个依赖于1.x的jersey-client的库,而我在使用它时遇到了一些麻烦在类路径上共存。看起来正在发生的事情是HK2正在发现任何从javax.ws.rs。*实现提供程序并试图实例化它们的东西。当它是来自Jersey 1.x的一个类时,它所需的依赖注入就不存在了,我最终会遇到很多错误:

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)

有没有办法让Jersey 2.x / HK2忽略com.sun.jersey。*包空间中的任何内容?

1 个答案:

答案 0 :(得分:10)

看来org.glassfish.jersey.internal.ServiceFinder的默认行为是通过类路径上的META-INF / services查找服务实现。但是,它有一个setIteratorProvider方法,允许您设置备用ServiceIteratorProvider实现。我能够通过为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"));
    }
}