EJB 3.1 Timer Simple Example
This is a simple webapp that polls a web site to check if a product is available. It uses a stateless session bean and calendar-based timer.
package test;After compiling, simply package test/InventoryCheckBean.class into a WAR file under WEB-INF/classes. No other files are needed.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.util.logging.Logger;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
@Stateless
public class InventoryCheckBean {
private static final String PRODUCT_URL = "http://www.amazon.com/dp/B002BSA298/";
private static final String IN_STOCK = "In Stock";
@SuppressWarnings("unused")
@Schedule(dayOfWeek = "0-5", hour = "0/2", minute = "0/20", timezone = "America/Los_Angeles")
private void checkInventory() {
BufferedReader br = null;
try {
String line = null;
URL url = new URI(PRODUCT_URL).toURL();
br = new BufferedReader(new InputStreamReader(url.openStream()));
while ((line = br.readLine()) != null) {
if(line.indexOf(IN_STOCK) >= 0) {
//email notify
Logger.getLogger("").info(line);
break;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if(br != null) {
try {
br.close();
} catch (IOException e) { //ignore
}
}
}
}
}
/tmp > jar tf $owd/inventory.warDeploy this war to any application server that is Java EE 6 compliant. The timer is activated upon successful deployment, and starts to check the specified site at the specified intervals. This is so-called automatic timer.
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/test/
WEB-INF/classes/test/InventoryCheckBean.class
In the server log file, you will notice these logs:
[#|2010-04-01T10:50:01.644-0400|INFO|glassfishv3.0||_ThreadID=26;_ThreadName=Thread-1;|<span class="availGreen">In Stock.</span><br/ > Ships from and sold by <b>Amazon.com</b>. Gift-wrap available.|#]Note:
(1) This WAR file contains only an EJB bean class.
(2) There is no business method in this EJB; only 1 private timer method, which is only invoked by the container after deployment. So @SuppressWarnings is used to mute any warnings that this method is never used.
(3) No client action is needed. Right after deployment, the timer is activated and starts the processing specified in the timer method.
(4) timezone is optionals and defaults to that of the hosting machine.
(5) This timer goes off every 20 minutes of every other hour starting from 0 o'clock from Sunday to Friday, and the time is based on America/Los_Angeles timezone.
Update on 3/4/2011, I deployed the same inventory.war to JBoss AS 6.0, by copying it to $JBOSS_HOME/server/default/deploy, it also worked. No need to change anything.
7 comments:
Wouldn't dayOfWeek = "0-5" produce a Sunday through Friday, not Monday through Friday? Standard cron ranges are from 0-6 starting on Sunday, not 0-7. Off by one error?
Yes, you are right. "0-5" means Sun - Fri. Corrected in the post. Thanks.
Hello,
I am using WebSphere 7 to deploy this timer and it is not starting the timer automatically.
Do you have any idea why?
Is it just supported to Glassfish?
This example is portable and should work in any appserver that is JavaEE 6 compatible. At least the target appserver should support EJB 3.1 and JavaEE 6 Web Profile. It's possible your appserer does not support it yet.
It wouldn't work on WebSphere 7 since it isn't Java EE 6 compatible. As of today, Glassfish is the only compatible AS.
Is it possible to inject a "JMS" resouce in a timer? I'm not able to although the same annotations do work in a SLSB implementing a WS.
You inject resources including jms resources into any Java EE components (certain standard types of classes in Java EE programming model). There is no such component as timer. EJB timers all run in EJB beans. Of course you can inject any supported resources into ejb bean class.
Post a Comment