Tuesday Aug 25, 2009

Jersey Test Framework re-visited!

   One of the previous entries introduced the Jersey Test Framework, which has since been adopted and used by a good number of developers. However, there has been some feedback suggesting ways for making the framework a better one.

Based on all this feedback, we have worked on making some changes in the framework. With the release of Jersey 1.1.2-ea, we have this new version of the framework which is better than the previous version in the following ways:

  • Introduced the concept of test container factories
  • Various test container types, defined by the different test container factory implementations
  • Support for the new In-Memory or In-Process test container
  • Loosely-coupled with the test container factory implementations
  • Loose coupling allows the definition and pluggability of custom test container factory implementations
  • Support for running tests on an application pre-deployed on an external container

But, there have been some major changes in the API, which seemed obvious for the cause.

This entry will describe what are the API changes, and how an user test can be defined, etc.

Breaking changes from 1.1.1-ea to 1.1.2-ea

  • The maven project groupId has changed from “com.sun.jersey.test.framework” to “com.sun.jersey”. 
  • The extending of Jersey unit test and configuration has changed.

                   The test class has to just pass an instance of AppDescriptor. For instance, the constructor of the spring-annotations sample test, passes this information as follows:

 public SpringAnnotationsWebAppTest() throws Exception {
      super(new WebAppDescriptor.Builder("com.sun.jersey.samples.springannotations.resources.jerseymanaged")
                .contextParam("contextConfigLocation", "classpath:applicationContext.xml")

           Note the use of the Builder design pattern, which makes it really easy to define an instance of the AppDescriptor while defining all the application attributes.

  • The test container type with which to run the tests has to be specified using the System Property test.containerFactory. Note that it used to be container.type till the previous version.
  • Unlike the previous implementation, the test container type value is not a string which maps to the container type, but the fully qualified class name of the test container factory is passed as value for the property test.containerFactory.
  •    mvn test -Dtest.containerFactory=com.sun.jersey.test.framework.spi.container.grizzly.web.GrizzlyWebTestContainerFactory 

About the AppDescriptor

            AppDescriptor is an abstract class which is extended by two classes - the LowLevelAppDescriptor and the WebAppDescriptor. These classes allow the definition of the various attributes of the application - like its context-path, url-pattern, root resource classes or packages, etc. While the LowLevelAppDescriptor can be used is cases were tests are to be run on light-weight containers like Grizzly or HTTPServer, the WebAppDescriptor is used in cases where tests could be run on the web-based containers like EmbeddedGlassFish, Grizzly Web Container, and the light-weight containers as well\*.

Test Container Factories

       The test framework comes with a set of test container factory implementations which are responsible for creating the test container(s).

The following low-level test container factories are provided:

The following Web-based test container factories are provided:

Running Tests using Maven

      As previously said, the container on which the tests have to be run is specified using the system property test.containerFactory which holds the fully-qualified classname of the test container factory which creates an instance of the test container, i.e.,

          mvn clean test -Dtest.containerFactory=<container-factory fully-qualified class name>


           1. If tests are to be run on external container like GlassFish, the application has to be explicity deployed on the container before running the tests.

               a. Package the application:

               mvn clean package -Dmaven.test.skip=true

               b. Deploy the generated application war file 

               c. Run the tests:

              mvn test -Dtest.containerFactory=com.sun.jersey.test.framework.spi.container.external.ExternalTestContainerFactory

           2. If the  tests are to be run on EmbeddedGlassFish, one additional property container.type has to be set along with test.containerFactory:

              mvn clean test -Dtest.containerFactory=com.sun.jersey.test.framework.spi.container.embedded.glassfish.EmbeddedGlassFishTestContainerFactory -Dcontainer.type=EmbeddedGF 

           3. If the property test.containerFactory is not set, the tests would be run on the Grizzly Web container by default.


Enable Logging

The framework allows the logging of the HTTP requests and responses being sent over the wire during the test process. All that is needed to enable this logging is set the flag enableLogging.

           mvn clean test -Dtest.containerFactory=<test container factory class> -DenableLogging

Programmatically setting the test container factory

      The framework also allows setting the test container factory programmatically. This could be done by overriding the JerseyTest class's getTestContainerFactory method and returning the appropriate test container factory's instance. For example if Grizzly Web container has to be set as the default test container factory, it could be done as follows:

    protected TestContainerFactory getTestContainerFactory() {
        return new GrizzlyWebTestContainerFactory();

                       That's a brief description of the new version of the Jersey Test Framework. Please send an email to the Jersey user's mailing list users@jersey.dev.java.net  in case you have any issues. Wish you a happy testing of your RESTful Web Services :)       

Thursday Nov 27, 2008

JAX-RS: Java API for RESTful web services

[Read More]

An introduction to RESTful Web Services

What is REST?

        REST is an acronym for one popular architectural style, Representational State Transfer. It is an architectural style for building distributed software systems like the WWW. It is modeled after the way data is represented, accessed and modified on the web. This is based on Chapter 5 of Roy Fielding's PhD dissertation.

In the REST architecture, data and functionality are considered resources, and these resources are accessed using URIs. The core principle of REST is - 'Everything is a resource'. For the same reason, it is quiet often referred to as "resource-oriented architecture".

RESTful Web Services

     RESTful Web Services are web services which are built on the REST architecture. These services expose the resources through web URIs. The following HTTP methods are used to create, retrieve, update and delete (CRUD) resources:

  • POST
  • GET
  • PUT

   RESTful web services might be programmed in such a way that they serve data of various mime-types. For instance, they might take requests and respond with following types of data depending on the accept-type request header:

  • Plain-Text (text/plain)
  • HTML (text/html)
  • JavaScript Object Notation (application/json)
  • XML (application/xml)

RESTful Web Services vs SOAP Web Services

 ROA - Resource oriented architecture
 SOA - SOAP oriented architecture
 Response is encapsulated in HTTP envelope.
 Response is encapsulated in SOAP envelope, which in turn is encapsulated in HTTP envelope.
WADL describes the web service.
WSDL describes the web service.
 Light weight, easy to develop.
 Heavy weight, complex.
 Tied to HTTP protocol
 Built on RPC


Naresh worked at Sun Microsystems for two years. During these two years he had worked on the Project Metro and Project Jersey.


« July 2016