Jersey Exception : SEVERE: A message body reader for Java class
Asked Answered
R

16

41

I have a Jersey based Rest WS which outputs JSON. I am implementing a Jersey Client to invoke the WS and consume the JSON response. The client code I have is below

WebResource r = restClient.resource(UriBuilder.fromUri("http://localhost/").port(8080).build());
String resp = r.path("/user").accept(MediaType.APPLICATION_JSON).get(String.class);
User[] users = r.path("/user").accept(MediaType.APPLICATION_JSON).get(User[].class);

The 2nd line outputs the JSON string response correctly, however the 3rd line to marshal JSON to the POJO is not happening and I get the following exception stacktrace

SEVERE: A message body reader for Java class [Lorg.shoppingsite.model.entity.jpa.User;, and Java type class [Lorg.shoppingsite.model.entity.jpa.User;, and MIME media type application/json was not found
Dec 21, 2011 11:32:01 AM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  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

I have the correct MIME TYPES in my request. My POJO has been annotated with XMLRootElement. What am I missing.

Thank you

Ronaldronalda answered 21/12, 2011 at 18:40 Comment(3)
Just FYI... In my case, the code ran fine inside IntelliJ but failed when it was packaged and deployed. I was using the maven-assembly-plugin with jar-with-dependencies option. I'm going to change to use Jackson ObjectMapper which is a work around.Astronaut
@Astronaut I am facing a similar issue. The code is running fine when its run using Intellij but throwing same error when packaged. Unlike you I don't have liberty to use Jackson ObjectMapper as the issue is in a dependency. Have you found an alternative solution to your problem?Molybdenous
@Ajay. The solution I marked worked for me. My guess is that in your IntelliJ you have some jar file that is needed or is "the right version" and it is picked over another file. These kinds of problems are difficult. I would suggest trying to use Shade Plugin (See maven.apache.org/plugins/maven-shade-plugin) and enable debugging to see what classes are duplicates. Most likely the code is pulling in the wrong version of a file when running outside of IntelliJ.Astronaut
R
35

I was able to fix the issue by adding the maven dependency for jersey-json.

Ronaldronalda answered 21/12, 2011 at 18:49 Comment(7)
This is correct, see this answer below for more detailed steps on adding the maven dependency.Torrence
In case of IntelliJ, adding jersey-json from maven in Project Structure wasn't enough. Adding the entry to pom.xml solved it.Snakeroot
I am facing the same issue and I have sdded jersey-json as well. But it dint solve the issues.Pozsony
That's terrible, @AmitGupta. What did you do?Magee
The issue was because of HTML response in case of err.Pozsony
In case someone else is in the same boat: this did not fix the problem for me (I already had a dependency on jersey-json). Instead, the root cause was that the server was not sending the Content-Type header I was expecting, and the Jersey client code was defaulting to application/octect-stream. Changing the server to return valid JSON with a matching header fixed it for me.Orthogenetic
@VDev, I have same issue because I added org.json.. After saw your answer I add jar from here. FYI I using eclipse - Jersey - Java - PostmanForkey
E
37

To make it work you only need two things. Check if you are missing:

  1. First of all, you need @XmlRootElement annotation for your object class/entity.
  2. You need to add dependency for jersey-json if you are missing.For your reference I added this dependency into my pom.xml.

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.17.1</version>
    </dependency>
    
Enroll answered 21/7, 2013 at 21:44 Comment(5)
just adding the jersey-json dependency was enough in my case.Saprophagous
NIce work! We have been chasing this jar for quite a bit... Thanks!Hoo
Seems odd @XmlBlahBlah is required for a JSON object, didn't help for me.Opalopalesce
i had to do both, adding annotation and maven dependencyNorval
You may also need to use maven shade plugin to merge META-INF/services/javax.ws.rs.ext.MessageBodyWriter and META-INF/services/javax.ws.rs.ext.MessageBodyReader of jersey-core and jersey-json library, please refer to https://mcmap.net/q/392416/-missing-standard-message-body-reader-providers-in-my-jarAtrium
R
35

I was able to fix the issue by adding the maven dependency for jersey-json.

Ronaldronalda answered 21/12, 2011 at 18:49 Comment(7)
This is correct, see this answer below for more detailed steps on adding the maven dependency.Torrence
In case of IntelliJ, adding jersey-json from maven in Project Structure wasn't enough. Adding the entry to pom.xml solved it.Snakeroot
I am facing the same issue and I have sdded jersey-json as well. But it dint solve the issues.Pozsony
That's terrible, @AmitGupta. What did you do?Magee
The issue was because of HTML response in case of err.Pozsony
In case someone else is in the same boat: this did not fix the problem for me (I already had a dependency on jersey-json). Instead, the root cause was that the server was not sending the Content-Type header I was expecting, and the Jersey client code was defaulting to application/octect-stream. Changing the server to return valid JSON with a matching header fixed it for me.Orthogenetic
@VDev, I have same issue because I added org.json.. After saw your answer I add jar from here. FYI I using eclipse - Jersey - Java - PostmanForkey
B
11

just put this

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
Botulism answered 1/8, 2012 at 16:0 Comment(2)
web.xml. See mkyong.com/webservices/jax-rs/json-example-with-jersey-jacksonExtravagancy
this suggestion along with adding jersey-json dependency solved my problem and I get a valid response from serverToenail
G
11

I know that this post is old and you figured this out a long time ago, but just to save the people who will read this some time.

You probably forgot to add annotation to the entity you are passing to the endpoint, so Jersey does not know how to process the POJO it receives. Annotate the pojo with something like this:

@XmlRootElement(name = "someName")
Goode answered 8/5, 2013 at 4:20 Comment(1)
This was required even after adding jersey-json to pom. +1Carrageen
S
9

If you are building an uberjar or "shaded jar", make sure your meta inf service files are merged. (This bit me multiple times on a dropwizard project.)

If you are using the gradle shadowJar plugin, you want to call mergeServiceFiles() in your shadowJar target: https://github.com/johnrengelman/shadow#merging-service-files

Not sure what the analogous commands are for maven or other build systems.

Scratches answered 22/4, 2015 at 20:50 Comment(3)
For Maven you add a transformer: ServicesResourceTransformer. This actually got me past this posted error message. However, it doesn't complain, but my .getEntity() call hangs instead. Something about json going on, because if I ask for a String entity, it doesn't hang.Opalopalesce
maven.apache.org/plugins/maven-shade-plugin/examples/… <-- documentation for the maven way.Melanite
Thanks, using ServicesResourceTransformer fixed this for me com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class org.x.y , and Java type class org.x.y and MIME media type application/xml; charset=UTF-8 was not found (notice mine didn't complain of json, but might still be applicable) (got the problem after adding more dependencies to my project)Saucedo
A
3

In my case, I'm using POJO. And I forgot configure POJOMappingFeature as true. Maycon has pointed it out in an early answer. However some guys might have trouble to configure it in web.xml correctly, here is my example.

<servlet>
    <servlet-name>Jersey Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
Agalloch answered 20/3, 2013 at 2:37 Comment(1)
or in code: clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);Opalopalesce
W
3

We also decided to use jersey as a solution. But as we are using org.JSON in most of the cases this dependency is unecessary and we felt not good.

Therefore we used the String representation to get a org.JSON object, instead of

JSONObject output = response.getEntity(JSONObject.class); 

we use it this way now:

JSONObject output = new JSONObject(response.getEntity(String.class)); 

where JSONObject comes from org.JSON and the imports could be changed from:

-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
Windburn answered 29/4, 2015 at 14:4 Comment(0)
C
3

Just add below lines in your POJO before start of class ,and your issue is resolved. @Produces("application/json") @XmlRootElement See example import javax.ws.rs.Produces; import javax.xml.bind.annotation.XmlRootElement;

 /**
 * @author manoj.kumar
 * @email [email protected]
 */
 @Produces("application/json")
 @XmlRootElement  
 public class User {

 private String username;
 private String password;
 private String email;
 public String getUsername() {
 return username;
 }
 public void setUsername(String username) {
     this.username = username;
 }
 public String getPassword() {
     return password;
 }
 public void setPassword(String password) {
     this.password = password;
 }
 public String getEmail() {
    return email;
 }
 public void setEmail(String email) {
    this.email = email;
 }

}
add below lines inside of your web.xml
<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>  
Now recompile your webservice everything would work!!!
Clancy answered 27/12, 2016 at 4:57 Comment(1)
what does xmlrootelement have to do with sending a JSON object?Donell
H
3

Try adding:

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>1.4</version>
</dependency>

Also this problem may occur if you're using HTTP GET with message body so in this case adding jersey-json lib, @XmlRootElement or modifying web.xml won't help. You should use URL QueryParam or HTTP POST.

Hillhouse answered 25/1, 2017 at 14:30 Comment(0)
D
0

You need to implement your own MessageBodyReader and MessageBodyWriter for your class Lorg.shoppingsite.model.entity.jpa.User.

package javax.ws.rs.ext;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyReader<T extends Object> {

    public boolean isReadable(Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public T readFrom(Class<T> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType, 
        MultivaluedMap<String, String> httpHeaders, 
        InputStream entityStream) throws IOException, WebApplicationException;
}

package javax.ws.rs.ext;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyWriter<T extends Object> {

    public boolean isWriteable(Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public long getSize(T t, 
        Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType);

    public void writeTo(T t, 
        Class<?> type, 
        Type genericType, 
        Annotation[] annotations, 
        MediaType mediaType, 
        MultivaluedMap<String, Object> httpHeaders, 
        OutputStream entityStream) throws IOException, WebApplicationException;
}
Delfinadelfine answered 11/2, 2012 at 11:59 Comment(1)
I think your approach is not the common way. Normally mapping of JSON to POJOs works with JAXB without creating an own messageBodyReader, because the message reader for JSON already exists. See answer of VDev.Kuchen
A
0

Just check if you are running different instances in eclipse. I quit all my other sessions, clean build fixed the problem

Automotive answered 31/1, 2013 at 12:50 Comment(0)
H
0

Some may be confused why add jersey-json jar can't solve this problem. I found out that this jar has to newer than jersey-json-1.7.jar( 1.7.0 doesn't work, but 1.7.1 works fine.). hope this can help

Haff answered 2/4, 2015 at 18:48 Comment(1)
This is a comment on the question or an attempt at an answer; please place it there when you are able.Pedicel
B
0

for Python and Swagger example:

import requests
base_url = 'https://petstore.swagger.io/v2'
def store_order(uid):
    api_url = f"{base_url}/store/order"
    api_data = {
        'id':uid,
        "petId": 0,
        "quantity": 0,
        "shipDate": "2020-04-08T07:56:05.832Z",
        "status": "placed",
        "complete": "true"
        }
    # is a kind of magic..
    r = requests.post(api_url, json=api_data)
    return r
print(store_order(0).content)    

Most important string with MIME type: r = requests.post(api_url, json=api_data)

Bethanie answered 8/4, 2020 at 8:37 Comment(0)
M
0

Q) Code was working fine in Intellj but failing in command line.

Sol) Add dependencies of jersey as a direct dependency rather than a transient one.

Reasoning: Since, it was working fine with IntelliJ, dependencies are correctly configured.

  1. Get required dependencies by one of the following:

    1. check for the IntelliJ running command. Stackoverflow-link
    2. List dependencies from maven mvn dependency:tree
  2. Now, add those problematic jersey dependencies explicitly.

Molybdenous answered 5/6, 2020 at 9:50 Comment(0)
H
0

I was able to fix it after updating my Java version (1.8 in my case). I was using get method in com.sun.jersey.api.client.WebResource.entity(, ).accept().get().

Heller answered 12/1, 2023 at 13:1 Comment(0)
H
-3

Mine was similar situation. I get this error in crucial times and I did not remember how I had solved it before, which I did many number of times. After strenuous hours of inspection, I have solved and reproduced the error and made sure how simple is the solution for this situation.

Okay - solution : remove (or correct) any newly made changes to your main project's properties files.

Yes, this is it. In fact, my project is a multi-moduled huge one, and you know going without correct dependencies is a rare case scenario as is fetched often from git (RAC too). My project was getting almost all configurable things from a properties file that is common to about 15 or so modules (sub projects) with good amount of intra-dependencies among them. jersey-json's dependency is always there in my merged parent pom. XML Annotations aren't a problem as the project is being run for around 100 times after modifying them. some solutions here point to web.xml and things like POJOMappingFeature. In my case, I haven't even touched the webapp module in this build. so anyhow, this solution worked for me and I am spending time to record this in SO in case if I ever happen to fall into this error, I would not have to waste my sleepy nights. (of course, for you too)

Hyphen answered 14/11, 2013 at 3:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.