SEVERE: A message body writer for Java class java.util.ArrayList and MIME media type application/json was not found
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.
Comments
-
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 over 10 yearsMichal regarding the last pont you have mentioned i.e. I tried with
json jersey-json 1.2
andjersey-core-1.2
, but problem persists. I need to try your first point, however I could find 1.2 version ofjersey-servlet
. I have been trying to resolve this issue since morning, however didn't succeed. -
Jacob over 10 yearsAnd 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 over 10 yearsThere is no
jersey-servlet
in 1.2 (this module has been introduced ~1.9). All the functionality should be injersey-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 handleList<Emp>
. Can you try to switch to 1.9 at least? -
Jacob over 10 yearsSo you mean to say I should try
1.9 jersey-server
instead of1.2
? If so I should iue all1.9
versions except forjersey-servlet
? -
Michal Gajdos over 10 yearsI 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 over 10 years1.9 version is not compatible with JDK1.5 version.
-
Jacob over 10 yearsI have tried your approach, however still I am having same errors. Same setup of what I already have and same versions of jars.
-
Jacob over 10 yearsMichal, 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 over 6 yearsI 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 about 6 yearsditto! what he said! ^