Closed jagraj closed 3 years ago
The error message:
java.lang.RuntimeException: A javax.ws.rs.ext.MessageBodyReader implementation was not found for class com.ibm.websphere.svt.gs.tax.entity.ShipRate type and application/octet-stream media type. Verify that all entity providers are correctly registered. Add a custom javax.ws.rs.ext.MessageBodyReader provider to handle the type and media type if a JAX-RS entity provider does not currently exist.
tells me that the Wink client, which is sending a request from com.ibm.websphere.svt.gs.gsjsfweb.utils.GarageSaleManagedBeanUtil.getShipRateByItemId(GarageSaleManagedBeanUtil.java:373)
Doesn't have a MessageBodyReader
that can de-serialize the ShipRate
object returned by the JAX-RS endpoint.
I have reproduced this with jaxrs-2.0
, jaxrs-2.1
and restfulWs-3.0
.
The solution is to register a MessageBodyReader
that can de-serialize ShipRate
with the client.
I manually forced my client to specify application/xml
for both Content-Type
and Accept
headers, and the server side does not have a MessageBodyWriter (without enabling the EE9 JAX-B feature) as well.
Adam he has a MessageBodyReader that can de-serialized ShipRate when receiving application/xml. When I looked at the wink code it does not look at the Consumes state if the Content-Type header is not set. CXF does look at the Consumes MediaType if Content-Type is not set. It appears that CXF does set the Content-Type header when sending back the response, but RestEasy does not. At least that is how I understood the problem when working with Jag on it.
Ok, that's good to know, thanks Jared.
So from what I can tell for this issue, the RestEasy code would need to be updated to return a Content-Type depending on the produced content. Either that or the application needs to be updated to set the Content-Type and we would need to document that as a limitation with restulfulWS-3.0. Jag, did the workaround to set the Content-Type work for you?
I did try workaround and that did not help. Some how we are still not getting headers from the response. Here is the info that we got from the trace.
EE9:
[9/14/21, 15:34:18:889 CDT] 00000037 id=00000000 org.apache.wink.client.internal.log.Responses 1 handle The received response headers:
Content-Language en-US
Content-Length 0
EE8:
[9/14/21, 16:05:16:354 CDT] 00000035 id=00000000 org.apache.wink.client.internal.log.Responses 1 handle The received response headers:
Content-Language en-US
Content-Length 186
Content-Type application/xml
Date Tue, 14 Sep 2021 21:05:16 GMT
X-Powered-By Servlet/4.0
[9/14/21, 16:21:54:698 CDT] 00000039 id=9e7c3cb6 iberty.restfulWS.internal.globalhandler.RESTfulWSHandlerImpl < execute Exit
[9/14/21, 16:21:54:698 CDT] 00000039 id=9e7c3cb6 iberty.restfulWS.internal.globalhandler.RESTfulWSHandlerImpl < filter Exit
[9/14/21, 16:21:54:698 CDT] 00000039 id=00000000 com.ibm.ws.webcontainer.srt.SRTServletResponse > setStatus ENTRY status --> 204 [com.ibm.ws.webcontainer40.srt.SRTServletResponse40@14d6f273]
it looks like after invoking the global handler's filter method, the status is set to 204 (no content) so I think the global handler might be eating the response object somehow.
I've been working on a solution to introspect Resteasy classes for tracing and I'm hoping to get more trace to narrow down the problem.
public void validateReturnValue(HttpRequest request, Object object, Method method, Object returnValue, Class<?>... groups)
[9/16/21, 11:14:16:526 CDT] 00000039 id=3b587fa6 org.jboss.resteasy.plugins.validation.GeneralValidatorImpl > validateReturnValue Entry
org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest@120b1fa
Proxy for com.ibm.websphere.svt.gs.tax.session.ProductTaxShipSessionBeanLocal$ProductTaxShipSessionBeanRemote$1425262761$Proxy$_$$_Weld$EnterpriseProxy$@b1904dca
public com.ibm.websphere.svt.gs.tax.entity.ShipRate com.ibm.websphere.svt.gs.tax.session.ProductTaxShipSessionBean.getShipRateByItemID(java.lang.String) throws java.lang.Exception
null
Interesting, it looks like the return value for getShipRateByItemID
is null
, which would explain why the server is sending back an HTTP 204 with no entity.
I modified the application to print out the ShipRate being returned by the server and found that it is indeed null
ProductTaxShipSessionBean.java
@GET
@Path("getShipRateByItemID")
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
public ShipRate getShipRateByItemID(String itemID) throws Exception {
String methodName ="getShipRateByItemID";
ShipRate shipRate=null;
try{
logger.logp(Level.FINE, className, methodName, "Calling getShipRateByItemID");
shipRate= taxAndShipRateSingletonBean.getShipRateByItemID(itemID);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("Adam: shipRate=" + shipRate);
return shipRate;
}
[9/16/21, 11:49:20:600 CDT] 00000039 SystemOut O Adam: shipRate=null
So, the REAL problem is that taxAndShipRateSingletonBean.getShipRateByItemID(itemID);
is returning null
in the application.
ShipRateSession.findShipRateById()
:
ShipRate shipRate = null;
EntityManager em = getEntityManager();
try {
shipRate = (ShipRate) em.find(ShipRate.class,
itemId);
} catch (Exception e) {
e.printStackTrace();
}
return shipRate;
The EntityManager
is returning null because the entity doesn't exist.
https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#find-java.lang.Class-java.lang.Object-
@WhiteCat22
After debugging the application I found out that String itemID
QueryParam is not passed to the resource method. I think this is related to this issue (https://github.com/OpenLiberty/open-liberty/issues/18210) where we need to set all annotations in bean class. After changing method signature with the QueryParam public ShipRate getShipRateByItemID(@QueryParam("itemID")String itemID)
then I no longer see this problem. This issue will be resolved once fix is delivered for issue #18210.
Thanks for your help in debugging this problem.
You're welcome!
Describe the bug JAX-RS application is failing after migrating from EE8 runtime to Jakarta EE9 with the RESTEASY runtime. My application endpoint defined with
@Produces(MediaType.APPLICATION_XML)
and@Consumes(MediaType.APPLICATION_XML)
and at the client side I am getting entity as XML data type but we are getting content type as null.Here is the exception from this failure.
Steps to Reproduce
Expected behavior Content type header must be set based on the annotation defined for the JAX-RS resource.
Diagnostic information:
$WLP_OUTPUT_DIR/messages.log
Additional context Add any other context about the problem here.