org.glassfish.jersey.internal.RuntimeDelegateImpl未找到。

47

我正在使用Jersey框架开发项目,想要从字符串中解析URI。

UriBuilder.fromUri("http://localhost:8000").build();

代码很简单,但我得到以下错误

java.lang.ClassNotFoundException: org.glassfish.jersey.internal.RuntimeDelegateImpl

程序似乎找不到委托。我已经导入了javax.ws.rs.core.UriBuilder并将jersey-common 2.0包含在我的构建路径中,应该包含委托。但我仍然遇到这个错误。

有人知道如何修复吗?谢谢!

7个回答

87
如果您正在使用Maven,请使用以下依赖项:
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-common</artifactId>
    <version>2.22.2</version>
    <scope>test</scope>
</dependency>

对于 Gradle,以下内容可以正常工作:

testImplementation 'org.glassfish.jersey.core:jersey-common:2.22.2'

3
你能解释一下为什么需要这个依赖吗? - Ismail Iqbal
6
如果您查看javax.ws.rs.ext.RuntimeDelegate#findDelegate,您会发现它默认使用org.glassfish.jersey.internal.RuntimeDelegateImpl。在生产环境中,您可能有其他实现方式,但这些实现方式无法用于测试。 - Andrew Swan
当我从cxf转换到spring-mvc时,我删除了一些cxf依赖项。按照您的建议添加依赖项解决了问题。 - mojave
+1 给 Andrew Swan 的解释 - 它非常有帮助,现在我可以看到代码中的原因了。我也正在从 cxf 迁移,并且对于为什么单元测试突然需要 JerseyFeignClient 感到困惑。 - java-addict301
2
为什么要指定测试范围?这个类不适合生产吗? - MiguelMunoz
不管是什么,生产环境中都会使用提供的内容。 - Archimedes Trajano

10

开发Wildfly 10.1运行时,我不想在构建中引入Jersey。使用Gradle:

testRuntime "org.jboss.resteasy:resteasy-jaxrs:$versions.resteasy"

resteasy版本是3.0.19.Final。此jar文件包含以下内容

META-INF/services/javax.ws.rs.ext.RuntimeDelegate

具有条目(entry)的

org.jboss.resteasy.spi.ResteasyProviderFactory

谢谢!我使用的是Quarkus,它也使用了Resteasy。我添加了这个,现在出错了:“Provider org.jboss.resteasy.spi.ResteasyProviderFactory无法实例化”。有什么想法吗? - Hamburml
加入这一行类似的代码对我有用!谢谢! testImplementation("org.jboss.resteasy:resteasy-jaxrs:_") ... version.org.jboss.resteasy..resteasy-jaxrs=3.15.6.Final - undefined

5
在我的案例中,问题是由于使用了另一个名为javax.ws.rs-api-2.0.jar的Jar文件。移除该Jar文件解决了我的问题。我使用的是以下这个Jar文件:
<include name="jersey-client-1.9.jar" />
<include name="jersey-core-1.9.jar" />
<include name="jersey-multipart-1.9.jar" />

4
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-common</artifactId>
    <version>2.26</version>
    <scope>test</scope>
</dependency>

我在使用Java 8和jersey-common 2.22.2时遇到了问题,但是使用2.26版本可以解决。


1

简而言之,如果您在应用程序中使用jersey-client 1.x,并且还有一个“提供者”类存在,并且您在那里有rs-api-2.1.jar,则需要添加jersey-server 1.x或删除rs-api-2.1(如果您同时也有jsr311-api-1.1.1)。

似乎是这种情况:

显然,当jersey-client首次启动时,它会尝试创建不同mime类型的“mime映射”。

jersey-core 1.x ContextResolverFactory:

  public void init(ProviderServices providersServices, InjectableProviderFactory ipf) {
    Map<Type, Map<MediaType, List<ContextResolver>>> rs = new HashMap();
    Set<ContextResolver> providers = providersServices.getProviders(ContextResolver.class);
    Iterator i$ = providers.iterator();

    while(i$.hasNext()) {
      ContextResolver provider = (ContextResolver)i$.next();
      List<MediaType> ms = MediaTypes.createMediaTypes((Produces)provider.getClass().getAnnotation(Produces.class));
       ...

如果有任何“提供者”存在(例如:@Produces ({MediaType.WILDCARD})),它会尝试查找它们的类型并将其添加到MIME类型列表中。但是,它是按照以下方式执行的:

如果您有rs-api-2.1.jar:

 private static RuntimeDelegate findDelegate() {
   try {
Object delegate = FactoryFinder.find("javax.ws.rs.ext.RuntimeDelegate", "org.glassfish.jersey.internal.RuntimeDelegateImpl", RuntimeDelegate.class);

如果你有以下的其他依赖,它似乎以稍微不同的方式实现:

jsr311-api-1.1.1.jar:

 private static RuntimeDelegate findDelegate() {
   try {
     Object delegate = FactoryFinder.find("javax.ws.rs.ext.RuntimeDelegate", "com.sun.ws.rs.ext.RuntimeDelegateImpl");

Jersey 1.x客户端提供了./jersey-client-.19/com/sun/ws/rs/ext/RuntimeDelegateImpl.class

而Jersey 1.x服务器提供了:

./jersey-server-1.19/com/sun/jersey/server/impl/provider/RuntimeDelegateImpl.class

Jersey 2.0是“org.glassfish.jersey...”,并提供了“org.glassfish.jersey.internal.RuntimeDelegateImpl”(显然很合理)

因此,我认为rs-api-2.1默认基于Jersey 2.x。但是,如果您还包括Jersey服务器,则它也可以与Jersey客户端1.x一起使用。

使用Jersey 2.x时,您不需要以这种奇怪的方式“使用服务器来使用客户端”,似乎只需正常工作即可。

我的直觉是API是否更改了(您不应该将Jersey 1.x与jsr-2组合使用?嗯?),或者可能是意外失误、错误或Jersey客户端1.x的设计不良,谁知道呢。

添加偶然添加“jersey 2.x”或“jersey-server 1.x”的事物也有效。

这些解决了以下运行时故障:

Caused by: java.lang.ExceptionInInitializerError: null
    at com.sun.jersey.core.spi.factory.ContextResolverFactory.init(ContextResolverFactory.java:86)
    at com.sun.jersey.api.client.Client.init(Client.java:340)
    at com.sun.jersey.api.client.Client.access$000(Client.java:119)
    at com.sun.jersey.api.client.Client$1.f(Client.java:192)
    at com.sun.jersey.api.client.Client$1.f(Client.java:188)
    at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:193)
    at com.sun.jersey.api.client.Client.<init>(Client.java:188)
    at com.sun.jersey.api.client.Client.<init>(Client.java:171)
    at redacted
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
    at org.familysearch.digitalarchive.aggregator.integration.ServiceAccountConfig$$EnhancerBySpringCGLIB$$a3409578.identityService(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 29 common frames omitted
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.glassfish.jersey.internal.RuntimeDelegateImpl
    at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:154)
    at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:121)
    at javax.ws.rs.core.MediaType.valueOf(MediaType.java:196)
    at com.sun.jersey.core.header.MediaTypes.<clinit>(MediaTypes.java:65)
    ... 48 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.glassfish.jersey.internal.RuntimeDelegateImpl
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:111)
    at javax.ws.rs.ext.FactoryFinder.find(FactoryFinder.java:209)
    at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:136)
    ... 51 common frames omitted

0
请使用UriComponents而不是URI。
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://localhost:8000").build();

然后你可以获取URI对象,如下:

uriComponents.toUri()

-1
compile 'org.springframework.boot:spring-boot-starter-jersey:1.2.0.RELEASE'

这对我有用!!!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接