This article, the third in a three-part series, compares Apache Wink with various other free and open source JAX-RS implementations like Project Jersey, JBoss RESTEasy, and the Restlet Framework. It provides a high-level overview of each implementation framework while highlighting differences based on a common set of attributes. Finally, this article helps you select the right framework for your needs by analyzing and reviewing the different JAX-RS implementations.
So, what are the main areas used to compare these different JAX-RS implementations? For the purposes of this article, I focus on five important areas. Obviously, there are many more features that you can use to compare JAX-RS implementations, but the five below are crucial for quick, easy, and efficient production-quality REST-based service development and testing:
- Embedded containers. Most JAX-RS implementations can be deployed within a servlet container, but sometimes, you want to run your REST-based service in an embedded manner within a non-servlet-based simple Java application. Be sure to determine which implementations support using embedded containers.
- Client API. JAX-RS defines sophisticated server-binding specifications but leaves it up to the implementation framework to define client bindings and APIs. Hence, client architecture and framework become a crucial attribute when selecting a JAX-RS implementation.
- Interceptor framework. REST-based Web service developers often need to pre- and postprocess HTTP invocations in a nonintrusive manner. These invocations are useful for actions like logging, caching, or security validation. Determine the mechanisms that your framework makes available to handle HTTP interceptions.
- Data format support. JAX-RS makes it easy to add support for any
data type using
MessageBodyReaderandMessageBodyWriterproviders. Determine the out-of-the-box support for common formats, including Atom, JSON, and MIME multipart data. - Component integration. Integrating with other frameworks is important in REST-based service development. Often, you're using other frameworks like Spring for dependency injection and other Model-View-Controller (MVC) frameworks for UI handling. Determine the native integration support of the JAX-RS implementation framework you've chosen with third-party components.
Project Jersey is Sun®'s open source, dual-licensed, production-quality JAX-RS reference implementation for building RESTful Web services. It's meant to be more than just a reference implementation and provides APIs that allow easy customization and extension by developers. Jersey ships as part of Sun’s GlassFish application server download.
Jersey is usually deployed within a servlet container but does support an embedded mode of operation within Java programs. Running a JAX-RS service in an embedded mode is easy and simple and requires only a few lines of code. You can also use this embeddable container easily with unit tests.
The Jersey client API is a sophisticated, high-level, Java-based API for invoking any RESTful Web service, not just JAX-RS-compliant services. JAX-RS developers however, should find the Jersey client API easy and familiar to use. The Jersey client API claims to have three important goals:
- Encapsulate the REST constraint of Uniform Interface Constraint on the client side.
- Make it as easy to interoperate with server-side RESTful Web services.
- Leverage JAX-RS API concepts and artifacts for the client side.
The Jersey client API also allows a pluggable HTTP implementation (like
HttpURLConnection and the Apache HTTP client).
Overall, the Jersey client API lets you efficiently implement a REST-based
client-side solution.
Listing 1 is an example of Jersey client code that enables
sending a POST request with form parameters
and receiving a response as a JAXB object.
Listing 1. Jersey client code
Form form = new Form();
f.add(“a”, “dim”);
f.add(“b”, “sum”);
Client client = Client.create();
WebResource resource = client.resource(“http://localhost:8080/formpost”);
JAXBBean bean = resource.
type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).
accept(MediaType.APPLICATION_JSON_TYPE).
post(JAXBBean.class, form);
|
It is important to note that the same code, if written using
HttpURLConnection, would have involved a lot
more work trying to serialize the form variables and de-serialize the response
to the JAXB bean.
Jersey provides a filter-based Interceptor framework that allows registering two types of filters:
- Container filters. Container filters filter the requests before resource filters.
- Resource filters. Resource filters filter responses before container filters.
Jersey, like other JAX-RS implementations, also provides JAX-RS extension
modules for supporting common formats, including Atom, JSON, and MIME
multipart data. Atom support requires a dependency on Apache Abdera as well
as the jersey-atom-abdera module.
Jersey currently provides extension-based support for two dependency injection frameworks: the Spring Framework and the Google Guice framework:
- Spring Framework. Spring support in Jersey requires a
dependency on the
jersey-springmodule. Spring support is enabled by referencing theSpringServletclass in the web.xml file. - Google Guice framework. Guice support is provided when
referencing the Guice filter
GuiceFilterand a Guice-specificServletContextListenerin the web.xml file.
If you have read the earlier parts of this article series, you already know a lot about Apache Wink. If you haven't, here's a quick overview.
Apache Wink version 1.0 is a fully compliant implementation of the JAX-RS 1.0 specification designed from the ground up. It is easy to use and production ready, and it provides a set of features that enhances the core JAX-RS specification, including:
Apache Wink 1.0 was designed to run inside a servlet container and currently does not support an embedded mode of operation. However, any compliant lightweight servlet container should be able to support the Apache Wink run time.
Apache Wink comes with a sophisticated built-in client framework. The Wink client framework provides a simple Java API to make the task of implementing clients to consume HTTP-based RESTful Web services easy and straightforward. The Wink client framework is also useful as a stand-alone REST-based Java client framework.
The Apache Wink run time utilizes handler chains for processing requests. Specifically,
there are three kinds of handler chains: request, response, and error.
You customize the handler chain by extending the
org.apache.wink.server.handlers.HandlersFactory
class, overriding methods and specifying the new handler factory class in the
web.xml file of the application.
Apache Wink 1.0 is packed with an array of built-in providers that assist you in supporting various industry-standard data formats, including XML, Atom, the Atom Publishing Protocol (APP), RSS, JSON, CSV, HTML, OpenSearch, and multipart.
Apache Wink provides easy Spring integration through an additional module that comes with the core framework. The Apache Wink Spring integration module provides various features, including:
- Registering resources and providers as classes or Spring beans
- Resources/provider life cycle customization
- Ability to use Spring features, like Inversion of Control (IoC)
- Easy customization using hooks from within the Spring context
Apache Wink also supports the WebDAV protocol through an extension module. The
extension module helps with creation and processing of WebDAV responses.
Listing 2 is an example of using the WebDAVResponseBuilder
class to implement a JAX-RS resource that is associated with the
PROPFIND WebDAV HTTP method using the
WebDAVMethod.PROPFIND annotation.
Listing 2. Apache Wink WebDAVResponseBuilder example
@Path("books/{bookid}")
public class BookResource {
@WebDAVMethod.PROPFIND
@Consumes("application/xml")
@Produces(application/xml")
public Response propfindBook(@PathParam("bookid") String booked) {
SyndFeed feed = ...
return WebDAVResponseBuilder.propfind(feed);
}
}
|
JBoss RESTEasy is Red Hat®'s JAX-RS-compliant framework implementation. It is licensed under the GNU Lesser General Public License (LGPL) and can be used in any servlet-based environment.
The JBoss RESTEasy implementation comes with a lightweight embeddable servlet container called TJWS that you can use within unit tests to make remote invocations to JAX-RS Web services. You can use this embedded container to run unit tests without having to run an entire servlet container. Listing 3 is an example of using the embeddable container in RESTEasy.
Listing 3. JBoss RESTEasy embedded server example
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.jboss.resteasy.client.ClientRequest;
public class MainResource {
@Path("restresource")
public static class MyRestResource {
@GET
@Produces("text/plain")
public String get() {
return "Hello World";
}
}
public static void main(String[] args) throws Exception {
TJWSEmbeddedJaxrsServer server = new TJWSEmbeddedJaxrsServer();
server.setPort(8080);
server.getDeployment()
.getRegistry().addPerRequestResource(MyRestResource.class);
try {
ClientRequest request =
new ClientRequet("http://localhost:8080/restresource");
String message = request.getTarget(String.class);
System.out.println(message);
} finally {
server.stop();
}
}
}
|
RESTEasy provides a programmatic client API to submit HTTP requests while
also being JAX-RS-aware. To make client invocations, you must create an instance
of the org.jboss.resteasy.client.ClientRequest class.
The RESTEasy client framework runs on top of Apache HttpClient but can also
support using java.net.URLConnection as a backbone.
RESTEasy also has a built-in client proxy framework that is a slightly different way
of writing RESTful Java clients. It works by reusing the JAX-RS annotations on the
client side, using the annotations to turn a method call into an equivalent HTTP
request.
RESTEasy uses listener objects called interceptors, which can intercept
JAX-RS calls and reroute them. There are four different types of interceptors on
the server side depending on which stage of the invocation process you want to
intercept: MessageBodyReader interceptors,
MessageBodyWriter interceptors, and pre- and
postprocessing interceptors. The client side also has different types of
interceptors.
Similar to the other JAX-RS implementations discussed so far, RESTEasy supports most of the popular data formats, including XML, JSON, Atom, XML-binary Optimized Packaging (XOP), Fastinfoset, and multipart. Similar to the Jersey framework, RESTEasy provides support for the Apache Abdera Project. However, because the Abdera Project does not provide support for JAXB content, RESTEasy also provides a simple JAXB-annotated object model for Atom support.
Being a JBoss-driven implementation, it's not surprising that RESTEasy supports close integration with JBoss Seam. However, it also supports integration with other popular frameworks and standards like Enterprise JavaBean (EJB) technology (a Java Platform, Enterprise Edition [Java EE] standard), Spring, and Google Guice.
The Restlet Framework is slightly different from the other JAX-RS implementations you've seen so far in that it existed well before JAX-RS was finalized as a standard. It was designed as a lightweight REST-based Java framework with pluggable extensions for different functionalities. At a high level, the Restlet Framework consists of three parts:
- The Restlet API
- The Noelios Restlet Engine (NRE) implementing the API
- Optional Restlet extensions
An extension is available as part of the Restlet Framework that implements the JAX-RS specification, providing all of the JAX-RS features you've come to know and love.
The Restlet Framework has always been protocol independent to a large extent, and this has enabled it to be run under different deployment configurations, including stand-alone JAR files, servlet containers, Spring containers, and Google Web Toolkit. The Restlet Framework also supports its own XML-based configuration apart from being able to leverage Spring XML configuration mechanisms.
Restlet includes a client API that makes it easy to consume any remote
HTTP-based services, not just JAX-RS services. The Restlet Framework is
based on a connectors and components architecture, where a connector
enables communication between components, usually by implementing a
network protocol. By instantiating an object of the
org.restlet.Client class specific to the protocol
needed, you can invoke remote HTTP services.
The Restlet Framework uses a sophisticated router-based mechanism to route
URI calls within the application. A router is a Restlet or a resource that
associates a URI to the resource that handles all requests made to this URI.
By extending the abstract class
org.restlet.Filter and attaching it to an existing
router, it's possible to intercept calls to routers. Filters support some
processing before or after the handling of a call by a target Restlet.
Listing 4 is an example illustrating the default usage of a
router. It declares two routes—one associating the URI /books to
the resource BooksResource and the second one /books/bookName to the
resource BookResource.
Listing 4. Restlet router creation
// Create a router Restlet that defines routes.
Router router = new Router(getContext());
// Defines a route for the resource "list of Books"
router.attach("/books", BooksResource.class);
// Defines a route for the resource "book"
router.attach("/books/{bookName}", BookResource.class);
|
The Restlet Framework supports major data formats like XML, JSON, and Atom using extensions to its core framework. The Restlet extension for Atom provides a comprehensive Atom API for both feeds and publication. The API is capable of parsing and formatting Atom and APP XML documents.
With its extensive extension library, the Restlet Framework provides integration support with various different frameworks and standards like Spring, Jetty, Grizzly, Simple, JAXB, JAX-RS, JiBX, Velocity, and FreeMarker.
No comparison of software frameworks would be complete without some form of performance testing. Here's a brief description of the performance methodology used to perform a highly informal performance test measuring the relative throughput of various JAX-RS implementations. Note that this test is in no way meant to be a formal benchmark of JAX-RS frameworks and was only done to give you a general idea of their relative performance characteristics.
- Performance criteria. I used transactional throughput, normally
measured in transaction per second, as the metric of choice. In this
case, it's meant to be a single REST-based
GETrequest to the RESTful service running on the target JAX-RS framework. - Test framework. I used an open source performance testing framework called Grinder version 3.3 for purposes of simulating client request load.
- Sampling method. The sampling method defines how the actual
test metrics are collected. In this case, I used the
cyclemethod, where I ran the test for a fixed number of cycles, and a cycle is defined as one complete execution of the test script. In this performance test, I used a fixed cycle length of 1500, which is a large enough number to be statistically significant. - Service/system under test. To test the performance characteristics
of the JAX-RS frameworks, I chose a simple JAX-RS test service that
is little more than a glorified "HelloWorld" service and ported it over
to the various JAX-RS frameworks. Refer to the Download
section for the source code of the JAX-RS resource used. All JAX-RS
frameworks were run as a Web application in an untuned Apache
Tomcat server version 6.0.13 running on a Jrockit version 1.5 Java
Virtual Machine (JVM). Listing 5 is the sample RESTful
service that was used to test against.
Listing 5. JAX-RS service used for performance testing……. // The Java class will be hosted at the URI path "/transactions" @Path("/transactions") public class TransactionResource { @GET @Path("{pnref}") @Produces(MediaType.TEXT_HTML) public String doInquiry(@PathParam("pnref") String pnref) { try { return getMockTxnStatus(pnref).toString(); } catch (Exception e) { throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } private JSONObject getMockTxnStatus(String pnref) throws JSONException { JSONObject jsonObject = new JSONObject(); jsonObject = jsonObject .put("RESULT","127") .put("PNREF",pnref) .put("RESPMSG","DummyResponse") .put("AUTHCODE","ASSDS") .put("CVV2MATCH","true") .put("AVSADDR","dummyaddress") .put("AVSZIP","dummyzip") .put("IAVS","IAVS") .put("CARDSECURE","cardsecure"); JSONObject retObject = new JSONObject(); for(int i=0;i<100;i++) retObject.put("jsonbj"+i, jsonObject); return retObject; } }
- Test run. I ran the performance test separately on every JAX-RS
implementation framework. The sample JAX-RS service was ported to
each JAX-RS framework, and the test measured the mean and peak
throughput at the end of 1500 cycles on each framework.
Figure 1 illustrates the results of the performance tests.
Figure 1. Performance test results
- Analysis of performance test. As you can see from Figure 1, apart from the Restlet Framework, most of the other JAX-RS implementations have similar throughput metrics. Some of them are marginally better than others—for example, Apache Wink has the highest peak TPS metric, while Project Jersey has the highest mean TPS. Also, the relative ordering between mean TPS and peak TPS is largely the same. Based on these performance tests, you can say that Apache Wink, JBoss RESTEasy, and Project Jersey have similar performance characteristics, while the Restlet Framework might be slightly behind them. However, it is important to note that because this is not a formal benchmark for JAX-RS frameworks, varying loads and testing conditions might cause different results.
In this article, you got a brief overview of multiple JAX-RS implementations, including Project Jersey, Apache Wink, JBoss RESTEasy, and the Restlet Framework. The article used five main functional attributes to describe each of these frameworks: embedded container support, client API framework, interceptor framework, data format support, and component integration support. Though all of the above-discussed frameworks implement the same JAX-RS specification, the design and architecture of these various frameworks are very different.
Also, I ran an informal performance test on all of the JAX-RS frameworks discussed using a sample RESTful service and an open source performance testing tool. I analyzed the results of the performance test to compare and contrast the run-time characteristics of the various implementations.
Depending on your specific needs, you might find one or more of the above frameworks a better match. For example, if component integration is of primary importance, the Restlet Framework or RESTEasy might be a good choice. However, if extensive data format support and a sophisticated interception framework with high throughput characteristics is important, then Apache Wink might be a good fit for your needs. I hope this article has helped you understand the differences between the various open source JAX-RS implementations on the market and identify the one that best suits your needs
| Description | Name | Size | Download method |
|---|---|---|---|
| Article source code | TransactionResource.zip | 2KB | HTTP |
Information about download methods
Learn
-
Apache
Wink Developer Guide: Read the guide to get a more detailed overview of the
Apache Wink framework and its use.
-
Apache Wink Wiki: Explore the various aspects
of the Apache Wink project.
-
JBoss RESTEasy: Read more JBoss RESTEasy.
-
Project Jersey: Learn more about Project Jersey.
-
Restlet Framework: Explore the Restlet Framework.
-
The Grinder Load Testing Framework: Discover the
Grinder Framework.
-
RESTful Java with JAX-RS: Read
the book by Bill Burke (O'Reilly Media, 2009).
-
RESTful Web Services: Read
the book by Leonard Richardson and Sam Ruby (O'Reilly Media, 2007).
-
RESTful Web
services: The basics (developerWorks, Nov 2008): Read Alex Rodriguez's article
to get a basic understanding of the concepts of REST.
-
JSR 311: JAX-RS: Read the
Java API for RESTful Web Services specification.
- The developerWorks Web development
zone: Visit the Web development zone for extensive how-to information covering
various Web-based solutions.
-
The developerWorks Open source zone: Visit the
developerWorks Open source zone for extensive how-to information, tools, and
project updates to help you develop with open source technologies and use them
with IBM products.
-
developerWorks
technical events and webcasts: Stay current with the latest technology.
Get products and technologies
-
Apache Wink: Download
Apache Wink and get the source code and binaries of the latest version of the
framework along with other example projects.
-
Apache Tomcat Web Server
version 6.x: Download Tomcat.
-
Grinder: Download Grinder.
-
IBM
trial software for product evaluation: Build your next project with trial software available
for download directly from developerWorks, including application development tools and
middleware products from DB2®, Lotus®, Rational®, Tivoli®,
and WebSphere®.
Discuss
-
developerWorks blogs: Check out
our blogs and get involved in the developerWorks
community.

Vishnu Vettrivel is the Principal Consultant at PunditLabs, which specializes in enterprise consulting and technology, and he has over a decade of experience in architecting, designing, and developing mission-critical enterprise applications. Having worked extensively for Fortune 50 clients, he has helped craft strategic technical plans for many emerging technologies. You can reach him at http://www.linkedin.com/in/Vishnu.



