Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Chapter 17. Asynchronicity and messaging

Seam makes it very easy to perform work asynchronously from a web request. When most people think of asynchronicity in Java EE, they think of using JMS. This is certainly one way to approach the problem in Seam, and is the right way when you have strict and well-defined quality of service requirements. Seam makes it easy to send and recieve JMS messages using Seam components.
But for many usecases, JMS is overkill. Seam layers a simple asynchronous method and event facility over the EJB 3.0 timer service.

Asynchronicity

Asynchronous events and method calls have the same quality of service expectations as the container's EJB timer service. If you're not familiar with the Timer service, don't worry, you don't need to interact with it directly if you want to use asynchronous methods in Seam.
To use asynchronous methods and events, you need to add the following line to components.xml:
<core:dispatcher/>
Note that this functionality is not available in environments which do not support EJB 3.0.

Asynchronous methods

In simplest form, an asynchronous call just lets a method call be processed asynchronously (in a different thread) from the caller. We usually use an asynchronous call when we want to return an immediate response to the client, and let some expensive work be processed in the background. This pattern works very well in applications which use AJAX, where the client can automatically poll the server for the result of the work.
For EJB components, we annotate the local interface to specify that a method is processed asynchronously.
@Local
public interface PaymentHandler
{
    @Asynchronous
    public void processPayment(Payment payment);
}
(For JavaBean components we can annotate the component implementation class if we like.)
The use of asynchronicity is transparent to the bean class:
@Stateless
@Name("paymentHandler")
public class PaymentHandlerBean implements PaymentHandler
{
    public void processPayment(Payment payment)
    {
        //do some work!
    }
}
And also transparent to the client:
@Stateful
@Name("paymentAction")
public class CreatePaymentAction
{
    @In(create=true) PaymentHandler paymentHandler;
    @In Bill bill;
    
    public String pay()
    {
        paymentHandler.processPayment( new Payment(bill) );
        return "success";
    }
}
The asynchronous method is processed in a completely new event context and does not have access to the session or conversation context state of the caller. However, the business process context is propagated.
Asynchronous method calls may be scheduled for later execution using the @Duration, @Expiration and @IntervalDuration annotations.
@Local
public interface PaymentHandler
{
    @Asynchronous
    public void processScheduledPayment(Payment payment, @Expiration Date date);

    @Asynchronous
    public void processRecurringPayment(Payment payment, @Expiration Date date, 
      @IntervalDuration Long interval)'
}
@Stateful
@Name("paymentAction")
public class CreatePaymentAction
{
    @In(create=true) PaymentHandler paymentHandler;
    @In Bill bill;
    
    public String schedulePayment()
    {
        paymentHandler.processScheduledPayment( new Payment(bill), bill.getDueDate() );
        return "success";
    }

    public String scheduleRecurringPayment()
    {
        paymentHandler.processRecurringPayment( new Payment(bill), bill.getDueDate(), ONE_MONTH );
        return "success";
    }
}
Both client and server may access the Timer object associated with the invocation.
@Local
public interface PaymentHandler
{
    @Asynchronous
    public Timer processScheduledPayment(Payment payment, @Expiration Date date);
}
@Stateless
@Name("paymentHandler")
public class PaymentHandlerBean implements PaymentHandler
{
    @In Timer timer;
    
    public Timer processScheduledPayment(Payment payment, @Expiration Date date)
    {
        //do some work!
        
        return timer; //note that return value is completely ignored
    }

}
@Stateful
@Name("paymentAction")
public class CreatePaymentAction
{
    @In(create=true) PaymentHandler paymentHandler;
    @In Bill bill;
    
    public String schedulePayment()
    {
        Timer timer = paymentHandler.processScheduledPayment( new Payment(bill), bill.getDueDate() );
        return "success";
    }
}
Asynchronous methods cannot return any other value to the caller.

Asynchronous events

Component-driven events may also be asynchronous. To raise an event for asynchronous processing, simply call the raiseAsynchronousEvent() methods of the Events class. To schedule a timed event, call one of the raiseTimedEvent() methods. Components may observe asynchronous events in the usual way, but remember that only the business process context is propagated to the asynchronous thread.

 
 
  Published under the terms of the Open Publication License Design by Interspire