Tag Archives: SOA

JAX-RS resources in JAR files: how to use CDI to register it with the JAX-RS runtime

Imagine you are creating a JAX-RS resource called Resource, and bundling it into a JAR called resource.jar, as a reusable service.  A developer creating a WAR would use your JAR in WEB-INF/lib, ensure that the JAX-RS runtime is started, and the resource would be detected and exposed, right?

No, sadly, the JAX-RS runtime will not automatically be able to find resources from within JARs without some help. CDI to the rescue!

If we annotate our JAX-RS class with a CDI annotation, such as @ApplicationScoped or @RequestScoped, and include a beans.xml in our JAR, then CDI will inspect our JAR, register our resource as a CDI managed bean, and — as a side effect — also register our resource with the JAX-RS runtime.

If you don’t use this method, then the developer of the WAR has to do a little bit more work. He/she will have to write a javax.ws.rs.core.Application subclass and implement either the getSIngletons() or getClasses() method and mention our resource class explicity in there, in order to let JAX-RS runtime know about the Resource class.

By using CDI, we can make the life of a resource user—the developer of the WAR—easier.



Java EE 6 and modular JAX-RS services

Problem Statement

I often create custom web applications to support mobile products that have a few functions in common. For e.g., many web applications need to let users authenticate themselves from a mobile application. These functions are exposed to the mobile applications using a RESTful API. I’d like to create re-usable bundles of these services and add as many or as few of them as needed to my custom web application and write as little integration logic as possible, focusing all my time on the custom business logic of the product being developed.

Here is a “note-to-self” primer on how to go about bundling JAX-RS services in a jar and then using them from a war.

I assume that the projects are built using Maven and that they are being deployed to a Java EE 6 app container.

The REST API and the jar

Let’s create a jar project called resource (I assume you know how to create a jar using Maven).

The JAX-RS API dependency

First let’s get our dependencies lined up. Our code will refer to the JAX-RS APIs at least. The APIs are provided by the app container, so our dependency will be in the provided scope. The only question is, what GAV (groupId-artifactId-version triplet that uniquely identifies a dependency in Maven) vector to use?

Typical web applications have this in their pom.xml:


but I prefer dependencies from apache geronimo project instead (because the above dependency cannot be used in unit tests and does not allow me to download javadocs):


For illustration, we shall create a JAX-RS based REST API to manage a simple entity. For simplicity we shall not bother about where this entity is stored, retrieved from etc.

Here is my entity class:

// file src/main/java/net/nihilanth/demo/resource/GenericEntity.java
package net.nihilanth.demo.resource;

import javax.xml.bind.annotation.XmlRootElement;

public class GenericEntity {

    private long id;
    private String name;

    // getter, setters and constructors omitted

Note the @XmlRootElement annotation. This is needed so that I can marshal my entity to/from XML. It also automatically allows me to marshal it to/from JSON. If I were not using XML but only JSON, I’d still keep this annotation just because it easily lets me marshal my entity to/from JSON.

And I expose this as a REST resource:

// file src/main/java/net/nihilanth/demo/resources/GenericResource.java
package net.nihilanth.demo.resource;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.ws.rs.*;

public class GenericResource {
    private long nextId = 1;

    // in lieu of a database, we shall retrieve entities from a list
    List<GenericEntity> list = new ArrayList<GenericEntity>();

    // we create a few instances so that we can see something in our tests
    // in real life you'd have code to retrieve entities from a database etc.
    public GenericResource() {
        createEntity(new GenericEntity("alpha"));
        createEntity(new GenericEntity("beta"));
        createEntity(new GenericEntity("gamma"));

    public String createEntity(GenericEntity entity) {
        return "" + entity.getId();

    public List<GenericEntity> list() {
        return Collections.unmodifiableList(list);

And that’s all that is needed. I now compile and “install” the jar in my local repository (or eventually, publish to our corporate maven repository). I can’t see my REST API in action yet: I have to create a web application that uses my JAR first.

The web application

Let’s create a war project called, simply, webapp.

The JAX-RS API dependency and the JAR dependency

I replace the default javaee-web-api dependency put there by Maven with our geronimo based dependency, and also add a dependency to the jar we just created:

<!-- this the pom.xml depedencies section for my war -->


Using our REST API

The JAR we created above is included in our WAR as a dependency. We have to figure out a way to tell the app container to locate our GenericResource from the JAR and publish it. We also have to decide the URL under which the resource will be available. We decide that all our REST resources will be made available under the URL /resources under our context path. To coax the app container to search our JARs and instantiate any REST resources found in them, we create this class:

// file src/main/java/net/nihilanth/demo/webapp/JaxRsApplication.java
package net.nihilanth.demo.webapp;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

public class JaxRsApplication extends Application {

The exact name and package of the class is not important. It just has to exist in our WAR, and the important thing is that:

  • It extends javax.ws.rs.core.Application, which tell the app container that our WAR contains one or more JAX-RS resources
  • It is annotated with @ApplicationPath annotation, which tells the app container the relative path under which our JAX-RS resources will be available (“resources”, in this case).

And that’s it. We don’t even need a web.xml in this example. Just build and deploy the war to an app container (e.g., glassfish v3). Note:

  • My instance of glassfish is listening on port 8080 (the default). I can thus access my web applications from the URL http://localhost:8080/
  • I have specified nothing special regarding the context path of my web application. By default, therefore, the web application’s context name is the same as my war file name, that is, webapp. Thus I can access my web app at the URL http://localhost:8080/webapp/
  • In the @ApplicationPath annotation I specified that the JAX-RS resources be made available under “resources” URI; thus all my JAX-RS resources are available at the URL http://localhost:8080/webapp/resources/
  • Finally, in my GenericResource class, the annotation @Path specified that this resource in named generic. So the individual methods of the GenericResource will be available under the URL http://localhost:8080/webapp/resources/generic

So let’s give it a spin. Here is here how I list the existing GenericEntity instances from the command line:

$ curl -H 'Accept: application/json' 'http://localhost:8080/webapp/resources/generic'

We got the three entities we had pre-prepared. Let’s add a new one:

$ curl -X POST -A 'Accept: application/json' -H 'Content-type: application/json' -d '{"name": "foo"}' 'http://localhost:8080/webapp/resources/generic'

There we go! The new entity was added and its new ID, 4, was returned.


You might have noticed that the return type of the GenericResource.createEntity method is String, even though the underlying data type (the ID of the created entity) is long. Why? Because out of the box, JAX-RS implementations cannot convert long or java.lang.Long to an external media type. If we want to keep the method return type as a primitive type, we shall have to provide our own entity mapper. But that is fodder for another post.

Another issue you might notice is that after creating a new entity, if we try to list all the entities, we get the same three entities back. Our fourth entity is not listed. This is because a new instance of GenericResource is created for every new request. We will fix this issue in a subsequent article.

JAX-WS clients and embedded WSDL files

Search stackoverflow.com for JAX-WS and WSDL and you will see a lot of people asking questions like this:

The problem is i need to build a web service client from a file i’m been provided. I’ve stored this file on the local file system and , while i keep the wsdl file in the correct file system folder, everithing is fine. When i deploy it to a server or remove the wsdl from the file system folder the proxy can’t find the wsdl and rises an error.

The common suggestion to use the “wsdlLocation” command line option or the equivalent maven plugin configuration directive does not work. This suggestion does work though.

Here is a portable way to create a web service client. Say the WSDL file is in the directory “src/main/resources/wsdl/CardValidator.wsdl” (assuming a maven project) inside the project, then the following code can be used to create the web service client and this code will work from inside a war, a jar or even from the exploded classes directory as well:

public class App {

    public void someMethod() {
        URL wsdlURL = App.class.getClassLoader().getResource("wsdl/CardValidator.wsdl");
        QName qname =
            new QName("http://ws.creditcard.jaxws.demo.nihilanth.net/", "CardValidatorService");
        CardValidatorService cardValidatorService =
            new CardValidatorService(wsdlURL, qname);
        CardValidator cardValidator = cardValidatorService.getCardValidatorPort();

SaaS step-by-step

A short and sweet article on JavaWorld (RoadMap to SaaS) discusses the steps involved in taking a run of the mill web-app and making it a distributed service oriented system. Not heavy on the details but IMHO presents the things an architect needs to be thinking about in a very compelling progression. So compelling, in fact, that I must have another look at it when I am more awake.