EJB Timer persistence across restarts
cjalmeida Jun 11, 2008 11:55 PMI'm using Seam 2.0.0.GA and Jboss 4.2.2.GA.
Here's the scenario. Whenever certain business operation is complete (ie: a sale is confirmed by the customer) I need my Seam application to warn a remote application about that operation (ie: message the warehouse to ship the product). The remote application is a web-enabled legacy application - the integration done through HTTPS POST.
In order to ensure reliability, I used an @Asynchronous method that loops every 10 seconds until the POST is sucessfully complete and return HTTP 200 OK. It work as a charm as long as i don't try to restart the server or application. The persisted timers can't be restored, it blows giving this exception:
18:49:56,388 ERROR [TimerImpl] Error invoking ejbTimeout: javax.ejb.EJBException: java.lang.NullPointerException
I'm using EJB Timers, not Quartz - since they're easier to configure for persistence. I haven't seen a Seam application that depends on persistent timers reloading across server restarts or documentation explaining on how to make this work.
Below are the classes that can be used to reproduce this.
@Name public class SalesAction { @In WarehouseMessenger warehouseMessenger; public void sendToWarehouse(Sale sale) { Long salesId = sale.getId(); String sku = sale.getSKU(); int qty = sale.getQuantity(); String destination = sale.getDestination(); long interval = 10000; warehouseMessenger.shipProductMessage(salesId, sku, qty, destination, interval); } } @Name public class WarehouseMessenger { @In Timer timer; @In EntityManager entityManager; @Logger Log log; @Asynchronous @Transaction public void shipProductMessage(Long salesId, String sku, int qty, String destination, @IntervalDuration interval); { String url = "https://remoteserver/warehouse/ship"; /* Post method that uses apache httpclient */ int status = post(url,salesId, sku, qty, destination); if (status = 200) { // HTTP OK Sale sale = entityManager.find(Sale.class,salesId); sale.setWarehouseNotified(true); timer.cancel(); log.debug("Warehouse notified of shipping order"); } else { log.debug("Could not notify warehouse"); } } }