Adam Bien's Weblog

Tuesday Feb 09, 2010

Simplest Possible EJB 3.1 Timer


@Singleton
public class TimerService {
    @EJB
    HelloService helloService;
  
    @Schedule(second="*/1", minute="*",hour="*", persistent=false)
    public void doWork(){
        System.out.println("timer: " + helloService.sayHello());
    }
}

A timer doesn't have to be a singleton - it can be a @Stateless and even a @Stateful bean. The method doWork() will be invoked every second. There is no registration or configuration needed.

How to compile:

You will need the EJB 3.1 API in the classpath, or at least the @Singleton, @Schedule and @EJB annotation.

How to deploy:

Just JAR or WAR the interceptor with an EJB and put the archive into e.g: [glassfishv3]\glassfish\domains\domain1\autodeploy

Btw. the initial deployment of the entire WAR took on my machine:


INFO: Loading application SimpleTimer at /SimpleTimer
INFO: SimpleTimer was successfully deployed in 363 milliseconds.

How to use:

Another service can be easily injected to the timer and so invoked periodically:

@Stateless
public class HelloService {
    public String sayHello(){
        return "Hello from control: " + System.currentTimeMillis();
    }
}

And: there is no XML, strange configuration, libraries, additional dependencies needed...You will find the whole executable project (tested with Netbeans 6.8 and Glassfish v3) in: http://kenai.com/projects/javaee-patterns/ [project name: SimpleTimer].

[See also "Real World Java EE Patterns - Rethinking Best Practices"] 



*NEW* Workshop: "Real World Java EE 6/7 Bootstrap" and book: Real World Java EE Night Hacks--Dissecting the Business Tier

Comments:

Can you please show the Java API for managing timers? In every scenario I can think of, I would need a Java API, not annotations. For example, a user designs an ad-hoc report and wants to have it emailed to three people every Friday at 5:00 PM. Should I have to recompile my source code for this?

Posted by Ryan de Laplante on February 09, 2010 at 03:52 PM CET #

@Ryan,

o.k. then I will write a post especially for you :-). The API was always available, you had to use that. Annotation are new in Java EE 6. With EJB 3.1 comes also a fluent-API. Will write a post about that,

thanks for your feedback!,

adam

Posted by Adam Bien on February 09, 2010 at 04:24 PM CET #

Hi Adam,

I'd be very interested too in examples on how to use the new timer API dynamically inside the code at runtime!

Moreover I'd like to hear your experience regarding performance and capability of the timer API in JEE 6. I'm thinking about a plan to port a standalone application to JEE 6. The app in question currently uses the Quartz framework to handle jobs with all sorts of scheduling plans. Do you think this could lead to performance problems for the scheduler in JEE 6 to handle a few hundred jobs (just the scheduling, not the work the jobs do)? Maybe Glassfish v3 is already using Quartz under the hood?!?

I've already posted this question some time ago in your Kenai forum but unfortunately didn't get an answer yet.

Thanks in advance!

Marco

Posted by Marco Ehrentreich on February 10, 2010 at 03:37 PM CET #

Hi Adam

Have you configured persistent timer for clustered environment? It is very common requirement to execute background job only on single cluster node.

It looks very easy, just set up persistent=true attribute for @Schedule. But I'm wondering how this feature is provided by AS in a portable way. For clustered version of Quartz you have to configure datasource (connection and schema) for jobs store.

I'm really interested in timer support for clustered environment.

Thanks in advance,
Marcin

Posted by Marcin on February 16, 2010 at 10:23 AM CET #

Can the timer values be injected so that we don't have hard-coded values in the class?

Posted by jkilgrow on February 23, 2010 at 05:32 PM CET #

Hi Adam,
Timers CANNOT be created for stateful session beans.

The spec says so. I am wondering why you said they can : "A timer doesn't have to be a singleton - it can be a @Stateless and even a @Stateful bean. "

Did i miss something ?

Posted by Celinio Fernandes on March 11, 2010 at 01:20 PM CET #

Thanks: That was cleanly put and a great place to start from (and it works).

Posted by Brian Silberbauer on April 01, 2010 at 10:11 AM CEST #

@Celinio

It is true that if you use the API that MDBs and SLSBs cannot create timers from a postconstruct, but the EJB 3.1 annotation spec is supposed to allow for timer creation in SLSBs and MDBs

Posted by Matt on August 18, 2010 at 02:23 AM CEST #

Excellent resource, EJB 3.1 are optimized for many processes in the server side, Java is the language in which I always find a solution with less coding.

Thank you from Mexico.

Posted by Diana Flores on January 28, 2011 at 02:06 AM CET #

Hi Adam,

I tried to deploy the war file on a Glassfish cluster, but it fails with the following message:

Error occurred during deployment: Exception while deploying the app [SimpleTimer] : Failed to create automatic timers for TimerService -- EJB Timer Service is not available.

We use Glassfish 3.1.1.
Have you tested the war file on a cluster?

Regards,

Jeroen

Posted by Jeroen on September 09, 2011 at 01:13 PM CEST #

Are you using the Web Profile version of GlassFish?

Posted by Alexis MP on September 12, 2011 at 10:47 AM CEST #

@Alexis,

no, I'm always using the full version. It is just 30 MB difference and no noticeable runtime overhead between the both...

thanks!,

adam

Posted by Adam Bien on September 12, 2011 at 01:17 PM CEST #

Hi Adam,

We found the solution for this problem. It was not a cluster problem. The problem was that we changed the __TimerPool to a remote MySQL database. More information can be found on the Glassfish forum: http://www.java.net/forum/topic/glassfish/glassfish/error-deploying-timer-application-glassfish-311-cluster-fails-timerservice-not-availible-0.

Regards,

Jeroen

Posted by Jeroen on September 19, 2011 at 11:06 AM CEST #

Hi Adam ,
I'm wondered like jkilgrow. I read in the specifiaction too that you can create only timers from MDB, Sigleton When I try with JB7 create a Timer from stateful i get
Exception in thread "main" javax.ejb.EJBException: java.lang.IllegalStateException: JBAS014366: Session id hasn't been set for stateful component:Statefultest

Posted by Süleyman Vurucu on November 25, 2011 at 01:03 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
Meta
My Recent Book
Java One 2009/2011
...the last 150 posts
...the last 10 comments
Links
License