5

I've been trying for ages to get Tomee 1.5.2 JAX-RS work with Jackson. I think I've tried 100 ways.
Here is my last attempt:

I added in conf/system.properties the following:

openejb.cxf.jax-rs.providers = org.codehaus.jackson.jaxrs.JacksonJsonProvider, org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider 


I added in Tomee's lib folder:

  • jackson-mapper-asl-1.9.12.jar
  • jackson-core-asl-1.9.12.jar
  • jackson-jaxrs-1.9.12.jar


I have a simple JAX-RS class in a clean NetBeans Maven web project. Mirc is a POJO with name and car.

...imports
@Path("")
public class MyJson {
@GET
@Produces(APPLICATION_JSON)
public Object myMeth() {
    return new Mirc("Peter", "BMW");
}

I keep getting "No message body writer has been found for response class myclass".
What did I miss? How can I get it to work? I've checked all posts on stackoverflow without success.
I would really appreciate some help. Thanks.

zmirc
  • 825
  • 2
  • 11
  • 27

5 Answers5

9

I've finally figured out how to do it, thanks to Tomee's great support. So...here it is!

I'll start by explaining how this can be achieved in latest Tomee 1.6 JAX-RS version, which will soon be released as stable. It's very stable even now, by the way.

Supposing you have a Maven Java EE 6 web app project (use NetBeans to generate one), here are the steps:
1. Add Jackson dependency in pom.xml

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-jaxrs</artifactId>
  <version>1.9.13</version>
</dependency>

2. Create openejb-jar.xml in WEB-INF (the folder with web.xml) containing:

<openejb-jar xmlns="http://www.openejb.org/openejb-jar/1.1">
  <pojo-deployment class-name="jaxrs-application">
    <properties>
      cxf.jaxrs.providers = org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider
    </properties>
  </pojo-deployment>
</openejb-jar>

For more info about this config see 1 and 2
Edit from @rmannibucau: if you use a custom jaxrs Application subclass (with @ApplicationPath for instance) you'll set the qualified name of this class instead of "jaxrs-application" (which means the default application).
3. Create a JAX-RS Resource that won't work without Jackson (example: a plain List):

import java.util.Arrays;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/jackson")
public class Resource {

  @GET
  @Produces({MediaType.APPLICATION_JSON})
  public Object sayHelloJson() {
    return Arrays.asList(new String[]{"Peter", "pan", "Ihihi"});
  }
}

4. Deploy on Tomee 1.6.0 JAX-RS edition and launch the app at: http://localhost:8080/yourAppPath/jackson This guide was tested with version 1.6.0 2013.10.24 on NetBeans 7.4.

In case you want the latest Jackson, replace the previous dependency with the following:

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.2.3</version>
</dependency>

and modify openejb-jar.xml to contain:

cxf.jaxrs.providers = com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider  

Tomee 1.5.2
For this version, providers must be specified for each resource, so not at application level as in 1.6.0. More info can be found here.

zmirc
  • 825
  • 2
  • 11
  • 27
  • 1
    To be complete if you use a custom jaxrs Application subclass (with @ApplicationPath for instance) you'll set the qualified name of this class instead of "jaxrs-application" (which means the default application). – Romain Manni-Bucau Oct 29 '13 at 09:42
  • For configuring Jettison: http://www.adam-bien.com/roller/abien/entry/configuring_the_json_default_provider – zmirc Nov 10 '14 at 10:28
  • Here's an article as well: http://www.adam-bien.com/roller/abien/entry/using_jackson_in_tomee_as – zmirc Nov 13 '14 at 13:35
  • 1
    Any update for TomEE 8? :-) @JsonValue does not work for enums and enum name is returned instead of value. – Panu Haaramo Oct 31 '21 at 10:36
1

you can use this code:

...imports
@Path("")
public class MyJson {
@GET
@Produces(APPLICATION_JSON)
public String myMeth() {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.writeValueAsString(new Mirc("Peter", "BMW"));
}

is this solve your problem ?

you can use mapper.readValue() to convert String to Object

Mark T
  • 773
  • 4
  • 10
  • 22
  • It may work, so thank you, but what I'm aiming for is to get the same behaviour from Glassfish & Jackson, where no method calls are required. That's what I want. Otherwise, I could use the default JAX-RS implementation in Tomee. Therefore, I won't mark this as answered, because is not. Thanks for willing to help. – zmirc Jul 25 '13 at 09:14
1

I had to add:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
    <version>1.9.13</version>
</dependency>

To the pom. I got

 java.lang.ClassNotFoundException: org.codehaus.jackson.xc.JaxbAnnotationIntrospector

otherwise.

Ron
  • 776
  • 8
  • 14
1

I am using openejb standalone from the TomcatEE and wanted to globally use Jackson for all JSon requests.

Adding this property to the initial context at server startup did the trick. Sharing because this was tough to track down, maybe it can help someone else.

properties.setProperty("cxf.jaxrs.providers", "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider");
Jeremy Bunn
  • 641
  • 6
  • 17
0

I noticed that tomee 1.6.0 had gson-2.1 in its lib directory. So we can use gson instead of jackson and not depend on 6 jackson-related jars (which go along with jackson-jaxrs-json-provider). The GsonProvider (instead of JacksonJaxbJsonProvider) can be found here. I tested with a very simple example and it worked correctly.

Andre Silva
  • 4,782
  • 9
  • 52
  • 65