JAXWS 2.1 EA2 is out! We are continuing to add new features and improve quality with each successive releases.
Here are the new features with this release:
Its tested to work with Glassfish v2 M2 and Topmcat 5.x. Refer to ReleaseNotes for detail on installation instruction.
-vivek.JAXWS 2.1 EA | Users Guide | Tools | Samples | JAXWS Community |
The JAX-WS RI has a vendor extension that allows developers to bring back object state to the web service world. Normally, the JAX-WS RI only creates one instance of a service class, and have it serve all incoming requests concurrently. This makes it essentially impossible to use instance fields of the service class for any meaningful purpose.
Because of this, people end up coding like C, in anti-OO fashion. Either that or you end up with writing boiler-plate code to dispatch a request to the right instance of your real domain object.
The stateful web service support in the JAX-WS RI resolves this problem by having the JAX-WS RI maintain multiple instances of a service. By using
WS-Addressing behind the scene, it provides a standard-based on-the-wire protocol and easy-to-use programming model.
2. Usage
Application service implementation classes (or providers) who'd like to use the stateful web service support must declare @Stateful annotation on a class. It should also have a public static method/field that takes StatefulWebServiceManager.
@Stateful @WebService @Addressing class BankAccount { protected final int id; private int balance; Account(int id) { this.id = id; } @WebMethod public synchronized void deposit(int amount) { balance+=amount; } // either via a public static field public static StatefulWebServiceManager<BankAccount> manager; // ... or via a public static method (the method name could be anything) public static void setManager(StatefulWebServiceManager<BankAccount> manager) { ... } }
After your service is deployed but before you receive a first request, the resource injection occurs on the field or the method.
A stateful web service class does not need to have a default constructor. In fact, most of the time you want to define a constructor that takes some arguments, so that each instance carries certain state (as illustrated in the above example.)
Each instance of a stateful web service class is identified by an unique EndpointReference. Your application creates an instance of a class, then you'll have the JAX-WS RI assign this unique EPR for the instance as follows:
@WebService class Bank { // this is ordinary stateless service @WebMethod public synchronized W3CEndpointReference login(int accountId, int pin) { if(!checkPin(pin)) throw new AuthenticationFailedException("invalid pin"); BankAccount acc = new BankAccount(accountId); return BankAccount.manager.export(acc); } }
Typically you then pass this EPR to remote systems. When they send messages to this EPR, the JAX-WS RI makes sure that the particular exported instance associated with that EPR will receive a service invocation.
3. Things To Consider
When you no longer need to tie an instance to the EPR, use {@link #unexport(Object)} so that the object can be GC-ed (or else you'll leak memory.) You may choose to do so explicitly, or you can rely on the time out by using {@link #setTimeout(long, Callback)}. *
{@link StatefulWebServiceManager} is thread-safe. It can be safely invoked from multiple threads concurrently.
JAXWS 2.1 EA | Users Guide | Tools | Samples | JAXWS Community |
Web Service endpoints may choose to work at the XML message level by implementing the
Provider
interface. The related information about
Provider
endpoints is documented in
provider page. However
Provider
endpoints are synchronous i.e. they receive XML requests and they return XML responses synchronously in invoke() method. If the endpoint wants to spawn a thread to process the request, it would block the jax-ws runtime thread and has to manage all the low details synchronizing the threads when the response is available. Also blocking a thread doesn't really scale well especially when the underlying transport is capable of handling asynchronous request and responses. RI provides an implemention specific solution to this problem by introducing
AsyncProvider.
This is similar to
Provider
endpoints but the difference is that the endpoint implementations have to implement
AsyncProvider
interface.
AsyncProvider Example
The following example shows an
AsyncProvider
example that accesses the payload of the request.
For example:
@WebServiceProvider
public class AsyncProviderImpl implements AsyncProvider<Source> {
public void invoke(Source source, AsyncProviderCallback cbak, WebServiceContext ctxt) {...}
}
AsyncProvider
sample
AsyncProvider
endpoints.