Jersey 2调用WebService时RESTEASY003940错误求助
问题描述
使用JDK 1.8u341/WildFly 10开发Java Web应用,通过Jersey 2调用WebService时出错,异常触发在Client client = ClientBuilder.newClient();语句处。
依赖配置(pom.xml)
<dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>2.19</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>2.19</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> <version>2.19</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-json-provider</artifactId> <version>2.4.1</version> </dependency>
相关代码
MyService.java
@Path("/") public class MyService { private Client client; public MyService() { client = Client.getInstance(CONFIG.getProperty("url")); } @POST @Path("/sendInfo") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public void sendInfo(NotificationRequest notiRequest){ String firstName = notiRequest.getFirstName(); String lastName = notiRequest.getLastName(); client.notify(firstName, firstName); } }
Client.java
public class Client { private String url; private static Client instance; public static Client getInstance(String url) { if(instance == null){ instance = new Client(url); } return instance; } private Client(String url) { this.url = url; } public NotifyResponse notify(String firstName, String lastName) { NotifyResponse notiRes = new NotifyResponse(); Client client = ClientBuilder.newClient(); // 此处抛出异常 WebTarget webTarget = client.target(this.url + "?firstName="+firstName+"&lastName="+lastName); Response response = webTarget.request().get(); if(response.getStatus()!=200 && response.getStatus()!=400){ notiRes.setResult(0); LOG.info("HTTP connection failed " + response.getStatus()); response.close(); return notiRes; } Map rptaMap = (new Genson()).deserialize(response.readEntity(String.class), Map.class); if(rptaMap == null){ notiRes.setResult(0); LOG.info("NotifyResponse es nulo"); response.close(); return notiRes; } notiRes.setResult((Boolean)rptaMap.get("result") ? 1:0); response.close(); return notiRes; } }
异常日志
[WARN ] 21-11-2022 12:07:18 com.example.MyService.sendInfo(MyService.java:388) - java.lang.RuntimeException: RESTEASY003940: Unable to instantiate MessageBodyReader java.lang.RuntimeException: java.lang.RuntimeException: RESTEASY003940: Unable to instantiate MessageBodyReader at org.jboss.resteasy.plugins.providers.RegisterBuiltin.register(RegisterBuiltin.java:35) at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.getProviderFactory(ResteasyClientBuilder.java:340) at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.build(ResteasyClientBuilder.java:348) at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.build(ResteasyClientBuilder.java:53) at javax.ws.rs.client.ClientBuilder.newClient(ClientBuilder.java:114) at com.example.client.notify(Client.java:302) at com.example.MyService.sendInfo(MyService.java:370) 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.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205) Caused by: java.lang.RuntimeException: RESTEASY003940: Unable to instantiate MessageBodyReader at org.jboss.resteasy.spi.ResteasyProviderFactory.registerProvider(ResteasyProviderFactory.java:1437) at org.jboss.resteasy.spi.ResteasyProviderFactory.registerProvider(ResteasyProviderFactory.java:1368) at org.jboss.resteasy.plugins.providers.RegisterBuiltin.registerProviders(RegisterBuiltin.java:71) at org.jboss.resteasy.plugins.providers.RegisterBuiltin.register(RegisterBuiltin.java:31) ... 68 more Caused by: java.lang.RuntimeException: RESTEASY003325: Failed to construct public com.owlike.genson.ext.jaxrs.GensonJsonConverter(javax.ws.rs.ext.Providers) at org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:162) at org.jboss.resteasy.spi.ResteasyProviderFactory.createProviderInstance(ResteasyProviderFactory.java:2246) at org.jboss.resteasy.spi.ResteasyProviderFactory.addMessageBodyReader(ResteasyProviderFactory.java:806) at org.jboss.resteasy.spi.ResteasyProviderFactory.registerProvider(ResteasyProviderFactory.java:1432) ... 71 more Caused by: org.jboss.resteasy.spi.LoggableFailure: RESTEASY003880: Unable to find contextual data of type: javax.ws.rs.ext.Providers at org.jboss.resteasy.core.ContextParameterInjector$GenericDelegatingProxy.invoke(ContextParameterInjector.java:62) at com.sun.proxy.$Proxy200.getContextResolver(Unknown Source) at com.owlike.genson.ext.jaxrs.GensonJsonConverter.<init>(GensonJsonConverter.java:38) ...
解决方案
问题核心是WildFly 10自带的Resteasy(JAX-RS实现)与引入的Jersey 2冲突,同时Genson JSON转换器的初始化依赖上下文环境异常,可通过以下步骤解决:
排除WildFly自带的Resteasy模块
在WEB-INF目录下创建jboss-deployment-structure.xml,配置排除服务器自带的JAX-RS相关模块,避免与Jersey冲突:<jboss-deployment-structure> <deployment> <exclude-subsystems> <subsystem name="jaxrs"/> </exclude-subsystems> <exclusions> <module name="javaee.api"/> <module name="javax.ws.rs.api"/> <module name="org.jboss.resteasy.resteasy-jaxrs"/> <module name="org.jboss.resteasy.resteasy-cdi"/> <module name="org.jboss.resteasy.resteasy-jackson2-provider"/> <module name="org.jboss.resteasy.resteasy-genson"/> </exclusions> </deployment> </jboss-deployment-structure>明确使用Jersey的ClientBuilder
替换默认的ClientBuilder.newClient(),直接使用Jersey的实现类,避免加载Resteasy的客户端实现:// 替换原有的Client创建代码 org.glassfish.jersey.client.JerseyClientBuilder clientBuilder = new org.glassfish.jersey.client.JerseyClientBuilder(); Client client = clientBuilder.build();统一使用Jackson处理JSON
日志显示Genson是Resteasy自带的转换器,而项目已引入Jackson的JSON provider,可排除Genson的间接依赖,并手动注册Jackson提供者:- 在pom.xml中排除Genson(若有间接依赖):
<dependency> <!-- 替换为实际依赖 --> <groupId>xxx</groupId> <artifactId>xxx</artifactId> <exclusions> <exclusion> <groupId>com.owlike</groupId> <artifactId>genson</artifactId> </exclusion> </exclusions> </dependency> - 初始化客户端时注册Jackson提供者:
Client client = JerseyClientBuilder.createClient(); client.register(JacksonJsonProvider.class);
- 在pom.xml中排除Genson(若有间接依赖):
内容的提问来源于stack exchange,提问作者user3637971
相关产品推荐
相关产品推荐

