MATLAB Answers

0

REST Web Service call via Java does not find message body reader (MIME octet-stream)

Asked by Andy Hueni on 11 Mar 2013
We have developed a Java client/server application using REST and Jersey for the wrapping/unwrapping of data to be sent between client and server. This works fine within Eclipse as well as for the exported Jar file. We are now trying to use our Java client classes within Matlab to connect to the application server. This produces an error message related to the reader of the message body:
Mar 11, 2013 5:28:37 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class ch.specchio.types.User, and Java type class ch.specchio.types.User, and MIME media type application/octet-stream was not found
Mar 11, 2013 5:28:37 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
application/octet-stream ->
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.RenderedImageProvider
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
com.sun.jersey.core.impl.provider.entity.EntityHolderReader
com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class ch.specchio.types.User, and Java type class ch.specchio.types.User, and MIME media type application/octet-stream was not found
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:550)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:674)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:503)
at ch.specchio.client.SPECCHIOWebClient.getObject(SPECCHIOWebClient.java:1616)
at ch.specchio.client.SPECCHIOWebClient.connect(SPECCHIOWebClient.java:192)
at ch.specchio.client.SPECCHIOClientFactory.connect(SPECCHIOClientFactory.java:90)
at ch.specchio.gui.DatabaseConnectionDialog.actionPerformed(DatabaseConnectionDialog.java:117)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6382)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3275)
at java.awt.Component.processEvent(Component.java:6147)
at java.awt.Container.processEvent(Container.java:2083)
at java.awt.Component.dispatchEventImpl(Component.java:4744)
at java.awt.Container.dispatchEventImpl(Container.java:2141)
at java.awt.Component.dispatchEvent(Component.java:4572)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4619)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4280)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4210)
at java.awt.Container.dispatchEventImpl(Container.java:2127)
at java.awt.Window.dispatchEventImpl(Window.java:2489)
at java.awt.Component.dispatchEvent(Component.java:4572)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:704)
at java.awt.EventQueue.access$400(EventQueue.java:82)
at java.awt.EventQueue$2.run(EventQueue.java:663)
at java.awt.EventQueue$2.run(EventQueue.java:661)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$3.run(EventQueue.java:677)
at java.awt.EventQueue$3.run(EventQueue.java:675)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:674)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
It appears that the returned message body is no longer XML but an octet stream and this is presumably preventing the proper unwrapping by Jersey. Why this happens is beyond me. The jar files and class paths are set within the classpath.txt file:
/Users/andyhueni/Documents/workspace/SPECCHIO Types/bin
/Users/andyhueni/Documents/workspace/SPECCHIO Web Client/bin
/Users/andyhueni/Documents/workspace/SPECCHIO Web Client/lib/jersey-client.jar
/Users/andyhueni/Documents/workspace/SPECCHIO Web Client/lib/jersey-core.jar
Within Java, the classes, such as in this case User, have been annotated with the return type, ditto the web service methods:
@XmlRootElement(name="user")
public class User {
....
}
@GET
@Produces(MediaType.APPLICATION_XML)
@Path("login")
public User login() throws SPECCHIOFactoryException {
UserFactory factory = new UserFactory(getClientUsername(), getClientPassword());
User user = factory.getUser(getClientUsername());
factory.dispose();
return user;
}
Environment: - MATLAB R2011a - Eclipse Java EE, Juno Release 1 - Glassfish Server 3.1.2.2

  0 Comments

Sign in to comment.

2 Answers

Answer by Andy Hueni on 5 Apr 2013
 Accepted Answer

Here is part 2 of the solution to the problem, which not strictly connected to Matlab, but also occurred when trying to call the services from R. You have to use the "copy required libraries into a sub-folder" option when exporting the JAR from Eclipse. The information that tipped us off to this solution is at: http://stackoverflow.com/questions/2730589/jersey-message-body-reader-not-found-in-maven-built-jar.

  0 Comments

Sign in to comment.


Answer by Andy Hueni on 16 Mar 2013
Edited by Andy Hueni on 16 Mar 2013

I'm now in the position to answer part of the problem. The octect stream is the result of a missing header in the returned response. To figure this out, edit your Java code (if you got the source), to add a filter to your webservice. Optionally, you can also write the header and the body to a file (note that this somehow crashes the actual JAXB reading of the response, but no matter for this test). In that filter, the response type can then be forced to be "application/xml" by using a reflection. Doing so removes the 'octet stream' error.
It appears that somewhere in the calling stack, Matlab is setting the returned header to null; I have tried the same call from R, and there the header was preserved.
A remaining issue is that even so, no body readers are found for the xml either, i.e. the map of the known message body workers is presumably wrongly configured in the Jersey framework; how to configure that properly is my next endeavour.
The filter code looks like:
class MyClientFilter extends ClientFilter
{
@Override
public ClientResponse handle(ClientRequest cr)
throws ClientHandlerException {
// Call the next client handler in the filter chain
ClientResponse resp = getNext().handle(cr);
System.out.println("Reponse type: " + resp.getType());
System.out.println("Status : " + resp.getStatus());
boolean write_header_and_body_to_file = false;
if(write_header_and_body_to_file == true)
{
try {
FileWriter w = new FileWriter("/tmp/specchio_out.txt");
for(String key : resp.getHeaders().keySet())
{
List<String> s = resp.getHeaders().get(key);
w.write(key + " : ");
for(String str : s)
w.write(str + "\n");
}
InputStream buf = resp.getEntityInputStream();
while(buf.available() > 0) {
byte[] b = new byte[buf.available()];
buf.read(b);
w.write(new String(b));
}
buf.close();
w.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
// create header
InBoundHeaders h = new InBoundHeaders();
h.add("Content-Type", "application/xml");
try {
// set content type header in response
Field HField = ClientResponse.class.getDeclaredField("headers");
HField.setAccessible(true);
HField.set(resp, h);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resp;
}
The filter is added to your web service by (just before you call the service):
MyClientFilter f = new MyClientFilter(); web_service.addFilter(f);
out = web_service.path(buildPath(service, method, args)).accept(MediaType.APPLICATION_XML).get(objectClass);

  0 Comments

Sign in to comment.