Home | Download | PDF | API | FAQ | Search | Feedback | History

> ## Using the Timer Service

> Applications that model business work flows often rely on timed notifications. The timer service of the enterprise bean container enables you to schedule timed notifications for all types of enterprise beans except for stateful session beans. You can schedule a timed notification to occur at a specific time, after a duration of time, or at timed intervals. For example, you could set timers to go off at 10:30 AM on May 23, in 30 days, or every 12 hours.

> When a timer expires (goes off), the container calls the method annotated `@Timeout` in the bean's implementation class. The `@Timeout` method contains the business logic that handles the timed event.

> ### The Timeout Method

> Methods annotated `@Timeout` in the enterprise bean class must return `void` and take a `javax.ejb.Timer` object as the only parameter. They may not throw application exceptions.

>     @Timeout
>     public void timeout(Timer timer) {
>       System.out.println("TimerBean: timeout occurred");
>     }

> ### Creating Timers

> To create a timer, the bean invokes one of the `createTimer` methods of the `TimerService` interface. (For details on the method signatures, see the `TimerService` API documentation.) When the bean invokes `createTimer`, the timer service begins to count down the timer duration.

> The bean described in The timersession Example creates a timer as follows:

>     Timer timer = timerService.createTimer(intervalDuration,
>         "Created new timer");

> In the `timersession` example, `createTimer` is invoked in a business method, which is called by a client.

> Timers are persistent. If the server is shut down (or even crashes), timers are saved and will become active again when the server is restarted. If a timer expires while the server is down, the container will call the `@Timeout` method when the server is restarted.

> The `Date` and `long` parameters of the `createTimer` methods represent time with the resolution of milliseconds. However, because the timer service is not intended for real-time applications, a callback to the `@Timeout` method might not occur with millisecond precision. The timer service is for business applications, which typically measure time in hours, days, or longer durations.

> ### Canceling and Saving Timers

> Timers can be canceled by the following events:

> - When a single-event timer expires, the EJB container calls the `@Timeout` method and then cancels the timer.
> - When the bean invokes the `cancel` method of the `Timer` interface, the container cancels the timer.

> If a method is invoked on a canceled timer, the container throws the `javax.ejb.NoSuchObjectLocalException`.

> To save a `Timer` object for future reference, invoke its `getHandle` method and store the `TimerHandle` object in a database. (A `TimerHandle` object is serializable.) To reinstantiate the `Timer` object, retrieve the handle from the database and invoke `getTimer` on the handle. A `TimerHandle` object cannot be passed as an argument of a method defined in a remote or web service interface. In other words, remote clients and web service clients cannot access a bean's `TimerHandle` object. Local clients, however, do not have this restriction.

> ### Getting Timer Information

> In addition to defining the `cancel` and `getHandle` methods, the `Timer` interface defines methods for obtaining information about timers:

>     public long getTimeRemaining();
>     public java.util.Date getNextTimeout();
>     public java.io.Serializable getInfo();

> The `getInfo` method returns the object that was the last parameter of the `createTimer` invocation. For example, in the `createTimer` code snippet of the preceding section, this information parameter is a `String` object with the value `created timer`.

> To retrieve all of a bean's active timers, call the `getTimers` method of the `TimerService` interface. The `getTimers` method returns a collection of `Timer` objects.

> ### Transactions and Timers

> An enterprise bean usually creates a timer within a transaction. If this transaction is rolled back, the timer creation is also rolled back. Similarly, if a bean cancels a timer within a transaction that gets rolled back, the timer cancellation is rolled back. In this case, the timer's duration is reset as if the cancellation had never occurred.

> In beans that use container-managed transactions, the `@Timeout` method usually has the `Required` transaction attribute to preserve transaction integrity. With this attribute, the EJB container begins the new transaction before calling the `@Timeout` method. If the transaction is rolled back, the container will call the `@Timeout` method at least one more time.

> ### The timersession Example

> The source code for this example is in the `<INSTALL>``/javaeetutorial5/examples/ejb/timersession/timersession-ejb/src/java` directory.

> `TimerSessionBean` is a stateless session bean that shows how to set a timer. In the source code listing of `TimerSessionBean` that follows, note the `createTimer` and `@Timeout` methods. Because it's a business method, `createTimer` is defined in the bean's remote business interface (`TimerSession`) and can be invoked by the client. In this example, the client invokes `createTimer` with an interval duration of 30,000 milliseconds. The `createTimer` method creates a new timer by invoking the `createTimer` method of `TimerService`. `TimerService` which is injected by the container when the bean is created. Now that the timer is set, the EJB container will invoke the `timeout` method of `TimerSessionBean` when the timer expires--in about 30 seconds. Here's the source code for the `TimerSessionBean` class:

>     package com.sun.tutorial.javaee.ejb;

>     import java.util.logging.Logger;
>     import javax.annotation.Resource;
>     import javax.ejb.Stateless;
>     import javax.ejb.Timeout;
>     import javax.ejb.Timer;
>     import javax.ejb.TimerService;

>     @Stateless
>     public class TimerSessionBean implements TimerSession {
>       @Resource
>       TimerService timerService;

>     private static final Logger logger = Logger
>         .getLogger("com.sun.tutorial.javaee.ejb.
>             timersession.TimerSessionBean");

>       public void createTimer(long intervalDuration) {
>         Timer timer = timerService.createTimer(intervalDuration,
>             "Created new timer");
>       }

>       @Timeout
>       public void timeout(Timer timer) {
>         logger.info("Timeout occurred");
>       }
>     }

> ### Building and Packaging timersession

> In a terminal window, go to the`` `<INSTALL>``/javaeetutorial5/examples/ejb/timersession/` directory. To build `TimerSessionBean`, type the following command:

>     ant build

> This runs the `default` task, which compiles the source files and packages the application into an EAR file located at `<``INSTALL``>/examples/ejb/timersession/dist/timersession.ear`.

> ### Deploying timersession

> Now that the Java EE application contains the enterprise bean package and deploy the `TimerSessionBean` using `ant`:

>     ant deploy

> #### Running the Application Client

> To run the application client, perform the following steps.

> 1. In a terminal window, go to the `<INSTALL>``/javaeetutorial5/
>    examples/ejb/timersession/` directory.
> 2. Type the following command:

> `ant run`

> This task first retrieves the client JAR, `timersessionClient.jar` to the dist directory, and then runs the client. This is the equivalent of running:

> `appclient -client TimerSessionAppClient.jar`

> 3. In the terminal window, the client displays these lines:

> `Creating a timer with an interval duration of 30000 ms.`

> The output from the timer is sent to the `server.log` file located in the `<``JAVA_EE_HOME``>/domains/domain1/server/logs/` directory.

> View the output in the Admin Console:

> 1. Open the Admin Console by opening a web browser window to

> `http://localhost:4848/asadmin/admingui`

> 2. Click Application Server in the navigation pane.
> 3. Click View Log Files.
> 4. At the top of the page, you'll see this line in the Message column:

> `Timeout occurred`

> Alternatively, you can look at the log file directly. After about 30 seconds, open `server.log` in a text editor and you will see the following lines:

>     TimerSessionBean: timeout occured