Traditionally JAX-WS has never taken advantage of object state, just like servlet. That is, the container creates only one instance of your service class, and then have it serve all the requests concurrently. This makes it impossible to set values to instance fields, as you'll experience concurrency problem as soon as multiple threads hit your service.

So all too often the service code starts to look more like C code, not Java code, and I didn't like this at all. Since I started helping the JAX-WS RI, I've been trying to fix this. Yesterday, I finally managed to write one.

On HTTP, session is often used to store state. This technique is still useful for web services over HTTP. JAX-WS lets you do this today, but as you can see in Rama's example, this is not pretty at all. Especially the server side, which I quote below for your reference:

@WebService
public class Hello {
    @Resource
    private WebServiceContext wsContext;
    public int getCounter(){
        MessageContext mc = wsContext.getMessageContext();
        HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();
        // Get a session property "counter" from context
        if (session == null)
            throw new WebServiceException("No session in WebServiceContext");
        Integer counter = (Integer)session.getAttribute("counter");
        if (counter == null) {
            counter = new Integer(0);
            System.out.println("Starting the Session");
        }
        counter = new Integer(counter.intValue() + 1);
        session.setAttribute("counter", counter);
        return counter;

    }
}

Instead of writing this much code, with JAX-WS RI 2.1, you can do this:

@HttpSessionScope @WebService
public class Hello {
    int counter = 0;
    public int getCounter() {
        return counter++;
    }
}

The @com.sun.xml.ws.developer.servlet.HttpSessionScopeannotation tells the JAX-WS RI to create one instance ofHello per each HTTP session. No need to mess withWebServiceContext, nor with HttpSession manually. It's all nicely typed and concise.

Not only that, but what I really like about this is that you can do something like this completely outside the JAX-WS RI. This is based on publicly available extension point in the JAX-WS RI 2.1 called InstanceResolver. This provides a pluggability point where 3rd party could control how the JAX-WS RI dispatches incoming requests to service instances, and I only needed to write a little more code to implement this logic.

Then I define HttpSessionScope annotation with JAX-WS RI's meta annotation InstanceResolverAnnotation, to connect all those things together.

I've barely scratched the surface with this mechanism. There's already a variant of this that takes advantage of WS-Addressing (which is the "proper" way of doing stateful web services), and we can write another that loads instances from Spring, which allows you to take advantage of all its DI features and AOJ mechanisms. So stay tuned for future entries.

To play with this feature today, go download the JAX-WS RI 2.1 nightly. Also, I think we'll be posting a new EA relatively soon.