In this article, we are going to learn how to configure on TomEE 7.x or later with the legacy JSON provider used by TomEE 1.7.x.

This scenario is useful when you are migrating JAX-RS based applications and want to keep the legacy JSON processing from the Jettison library (v1.3.7) used by TomEE 1.7.x.

Since TomEE 7.x, The Johnzon library has been the default provider because it implements the JSON-P_1.1 (JSR-353) and JSON-B_1.0 (JSR-367) specifications.

Application and Server configurations

In order to enable Jettison as the JSON provider for TomEE 7.x or later you need to execute the following changes:

In your application

1.   Create under /webapp/WEB-INF/ in your application a file called resources.xml with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <Service id="json" class-name="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        SkipJaxbChecks = true
        DropRootElement = false
        SupportUnwrapped = true
        SingleJaxbContext = true
    </Service>
</resources>

2.   Create under /webapp/WEB-INF/ in your application a file called openejb-jar.xml with the following content that makes reference to the resource created in previous step. Notice that org.superbiz.JAXRSApplication is the fully-qualified name of the Class defining the JAXRS application in your project.

<?xml version="1.0" encoding="UTF-8"?>
<openejb-jar xmlns="http://www.openejb.org/openejb-jar/1.1">
    <pojo-deployment class-name="org.superbiz.JAXRSApplication">
        <properties>
            cxf.jaxrs.providers = json
        </properties>
    </pojo-deployment>
</openejb-jar>

In your TomEE server

1.   Include the jettison 1.3.7 jar in the TomEE $TOMEE_HOME/lib/ directory

Project test configurations

TomEE maven plugin

If you are using TomEE maven plugin, the jettison jar can be added via the libs tag in the plugin properties section from your project pom.xml file:

<build>
   <plugins>
       <plugin>
           <groupId>org.apache.tomee.maven</groupId>
           <artifactId>tomee-maven-plugin</artifactId>
           <version>${tomee.version}</version>
           <configuration>
               <tomeeClassifier>plus</tomeeClassifier>
               <context>${project.artifactId}</context>
               <libs>                                                   
                   <lib>org.codehaus.jettison:jettison:1.3.7</lib>
               </libs>
           </configuration>
       </plugin>
   </plugins>
</build>

Arquillian TomEE Embedded Container Adapter

In your file src/test/resources/arquillian.xml you can define the inclusion of Jettison 1.3.7 via the additionalLibs property.

<arquillian xmlns="http://jboss.org/schema/arquillian"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="
              http://jboss.org/schema/arquillian
              http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

  <container qualifier="server" default="true">
    <configuration>
      <property name="httpsPort">-1</property>
      <property name="httpPort">4444</property>
      <property name="stopPort">-1</property>
      <property name="ajpPort">-1</property>
      <property name="classifier">plus</property>
      <property name="simpleLog">true</property>
      <property name="cleanOnStartUp">true</property>
      <property name="dir">target/server</property>
      <property name="appWorkingDir">target/arquillian</property>
      <property name="additionalLibs">mvn:org.codehaus.jettison:jettison:1.3.7</property>
    </configuration>
  </container>
</arquillian>

Comparing the outputs

The TomEE example JAX-RS JSON Provider With Jettison shows with details the configurations described in the previous sections.

Item.java is the POJO that is going to be returned by the /api/catalog/books/ endpoint:

package org.superbiz;

import javax.xml.bind.annotation.*;

@XmlRootElement(name = "book")
@XmlAccessorType(XmlAccessType.FIELD)
public class Item {

    @XmlValue
    private String name;

    @XmlAttribute
    private int id;

    @XmlAttribute
    private String availableSince;

    @XmlAttribute
    private boolean available = false;

    public Item() {
    }

    public Item(String name, int id, String availableSince, boolean available) {
        this.name = name;
        this.id = id;
        this.availableSince = availableSince;
        this.available = available;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAvailableSince() {
        return availableSince;
    }

    public void setAvailableSince(String availableSince) {
        this.availableSince = availableSince;
    }

    public boolean isAvailable() {
        return available;
    }

    public void setAvailable(boolean available) {
        this.available = available;
    }
}

The output obtained by default using TomEE 7.x and later using Johnzon is the following is visible in the test TestWithoutJettison.java:

{"available":false,"availableSince":"2019-05-27 15:27:16.878","id":134,"name":"TomEE Tutorial"}

The output obtained by Jettison visible in the test TestWithJettison.java:

{"book":{"@id":"134","@availableSince":"2019-05-27 15:27:16.878","@available":"false","$":"TomEE Tutorial"}}

As you can see the output is different and this can impact existing applications, which is why some organizations need to keep jettison provider when upgrading to TomEE 7.x.

Cesar Hernandez

Cesar Hernandez

César Hernández is a Senior Software Engineer at Tomitribe with experience in Enterprise Java Applications. He is a Java Champion, Duke's Choice Award winner, Eclipse Committer, Open Source advocate, teacher, and public speaker. When César is away from a computer, he enjoys spending time with his family, traveling and playing music with the Java Community Band, The Null Pointers. Follow Cesar on twitter @CesarHgt
CesarHgt

Leave a Reply