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.