SEVERE: A message body writer for Java class java.util.ArrayList and MIME media type application/json was not found

76,722

Solution 1

Make sure you don't have multiple Jersey versions in your project. From the list you provided there are modules from 3 different versions (1.2, 1.10, 1.8). For some modules Jersey does a check that the version of a module is the same as the version of the core. If it's not then providers of the module (such as MessageBodyReaders, MessageBodyWriters) are not registered in the runtime. This can be problem in your setup - json vs core (1.8 vs 1.2).

Solution 2

The problem may be how you're trying to return your result. I have seen others write their service-layer code this way too, but Jersey provides a way to do it cleanly and it will support JSON, XML and HTML output which you only need to specify using your @Produces annotation. This is what I do:

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;

@GET
@Produces( MediaType.APPLICATION_JSON )
public Response getEmployees()
{        
    List< Emp >                  matched;
    GenericEntity< List< Emp > > entity;

    matched = myDAO.getAllEmployees();
    entity  = new GenericEntity< List< Emp > >( matched ) { };

    return Response.ok( entity ).build();
}

I'm using the following Jersey libraries:

  • jersey-core-1.8.jar
  • jersey-json-1.8.jar
  • jersey-server-1.8.jar

Solution 3

You cannot define the response Xml as List<Emp>, as the JAXB is unable to identify the @XmlRootElement over the java.util.List or java.util.ArrayList class definition.

Ideally, you should have one parent/root element for your collection of Child Elements.

Create one more Class as Employees to contains the Collection of Emp objects as like below and try it.

@GET
@Produces("application/json")    
public Employees getEmployees() {        
    List<Emp> empList = myDAO.getAllEmployees();
    log.info("size   " + empList.size());
    Employees employees = new Employees();
    employees.setEmployeeList(empList);

    return employees;
}

@XmlRootElement(name = "Employees")
public class Employees {

    List<Emp> employeeList;

    //setters and getters goes here
}

@XmlRootElement()
class Emp {
   //fields here
}

Please try this approach, it will work.

Solution 4

Add this to your pom.xml. Solved my problem.

        <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.18.1</version>
    </dependency>
    <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>0.99</version>
    </dependency>

Solution 5

Specifying @XmlRootElement(name = "yourclass") on the class you want to pass as output. This has solved the problem for me when I get this exception.

Share:
76,722
Jacob
Author by

Jacob

Downvote, at no time in the past or hitherto; not ever.

Updated on April 25, 2020

Comments

  • Jacob
    Jacob about 4 years

    I am testing RESTful services and when I execute I am getting exceptions although I have the following jars in my class path(WEB-INF/lib), I am not using Maven and my JDK version is 1.5. Other questions regarding this issue didn't help to resolve the problem.

    Code snippet

    @GET
    @Produces("application/json")    
    //@Produces({MediaType.APPLICATION_JSON}) tried this, didn't work either
    public List<Emp> getEmployees() {        
        List<Emp> empList = myDAO.getAllEmployees();
        log.info("size   " + empList.size());
        return empList;
    }
    
    @XmlRootElement
    public class Emp {
    ......
    

    web.xml

    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>test.employees</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>
    
     <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    

    List of jars

    jersey-server-1.2.jar
    jersey-core-1.2.jar
    jsr311-api-1.1.jar
    asm-3.1.jar
    jaxb-api-2.0.jar
    jaxb-impl-2.0.jar
    jackson-xc-1.2.0.jar
    jackson-jaxrs-1.2.0.jar
    jackson-mapper-asl-1.2.0.jar
    jackson-core-asl-1.2.0.jar
    jettison-1.2.jar
    jersey-client-1.2.jar
    jersey-servlet-1.10.jar
    jersey-json-1.8.jar
    

    Exception stack

     SEVERE: A message body writer for Java class java.util.ArrayList,
     and Java type java.util.List<test.Emp>, 
     and MIME media type application/json was not found
    Nov 21, 2013 11:47:26 AM com.sun.jersey.spi.container.ContainerResponse traceException
    SEVERE: Mapped exception to response: 500 (Internal Server Error)
    
    javax.ws.rs.WebApplicationException
        at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.java:97)
        at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.java:55)
        at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:267)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1035)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:947)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:939)
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:399)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:478)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:663)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
        at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:719)
        at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:376)
        at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:870)
        at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:451)
        at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:218)
        at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:119)
        at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:112)
        at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)
        at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:230)
        at oracle.oc4j.network.ServerSocketAcceptHandler.access$800(ServerSocketAcceptHandler.java:33)
        at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:831)
        at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
        at java.lang.Thread.run(Thread.java:595)
    

    How can I resolve this issue?

  • Jacob
    Jacob over 10 years
    Michal regarding the last pont you have mentioned i.e. I tried with json jersey-json 1.2 and jersey-core-1.2, but problem persists. I need to try your first point, however I could find 1.2 version of jersey-servlet. I have been trying to resolve this issue since morning, however didn't succeed.
  • Jacob
    Jacob over 10 years
    And Michal could you be kind enough to suggest what are the correct versions of all jars required to run on JDK1.5? Thanks
  • Michal Gajdos
    Michal Gajdos over 10 years
    There is no jersey-servlet in 1.2 (this module has been introduced ~1.9). All the functionality should be in jersey-server. Also I don't think that support for POJO mapping feature (com.sun.jersey.api.json.POJOMappingFeature) is in 1.2 which may mean that custom json parser is not able to handle List<Emp>. Can you try to switch to 1.9 at least?
  • Jacob
    Jacob over 10 years
    So you mean to say I should try 1.9 jersey-server instead of 1.2? If so I should iue all 1.9 versions except for jersey-servlet?
  • Michal Gajdos
    Michal Gajdos over 10 years
    I meant to use 1.9 for all Jersey modules (+ you'll be able to use Jackson for Java<->JSON which should be able to handle List<Emp>). Also the suggestion from @omega may be valid for some JSON parsers.
  • Jacob
    Jacob over 10 years
    1.9 version is not compatible with JDK1.5 version.
  • Jacob
    Jacob over 10 years
    I have tried your approach, however still I am having same errors. Same setup of what I already have and same versions of jars.
  • Jacob
    Jacob over 10 years
    Michal, as a work around, what I did is avoid using @Produces("application/json") and manually wrap json method whatever I return from database and return to REST method call. For this approach my method type is String or Object. E.g. public String getEmployees() { ...... String myjson = gsons.toJson(empList); return myjson; Hope this does follows REST standard or architecture.
  • Bassel Kh
    Bassel Kh over 6 years
    I didn't believe that this might resolve the problem, since the annotation is related to JSON not XML, but it worked!, you made my day, thank you very much
  • Victor Ramos
    Victor Ramos about 6 years
    ditto! what he said! ^