JBoss AS 6.0.0.M5 has just been released. This is mainly a bug fix release, in preparation for the upcoming 6.0.0.CR1 release.
What are the JBoss EJB3 changes in JBoss AS 6.0.0.M5:
There have been many user reported and other EJB3.x bug fixes that have been included JBoss AS 6.0.0.M5. Other than the bug fixes, there has been one important change to the way we deploy (our internal) JBoss EJB3.x timerservice. This change involves deploying (our internal) timerservice implementation "lazily". The timerservice is deployed only when the server has any EJB3.x deployments. The change was done to improve the JBoss AS boot time. The complete details of the change can be found here
Download:
So as always, go download the server from here and give it a try! Any issues/questions can always be asked in our user forum here
Release Notes:
You can find the release notes of JBoss AS 6.0.0.M5 here.
JBoss AS6 FAQ:
JBoss AS6 specific FAQ can be found here
Saturday, September 25, 2010
Sunday, August 22, 2010
MySQL installation error - Neither host nor 'localhost' could be looked up
While trying to install MySQL 5.1 on my Ubuntu system recently, I ran into an annoying error. I call it annoying because the error message turned out to be a bit misleading. I'll first mention the steps that I followed to install MySQL and the error that I ran into and finally the "fix" to get past the error.
System details:
- Ubuntu 10.04 Operating System
- MySQL 5.1.x downloaded from the official site here http://dev.mysql.com/downloads/mysql/ and selected the "Compressed TAR Archive" (mysql-5.1.50-linux-i686-glibc23.tar.gz to be precise) under the "Linux - Generic" platform
Installation steps:
- Extracted the .tar.gz locally to /home/jpai/MySQL/mysql-5.1.50-linux-i686-glibc23. In the rest of this article, I'll refer to this path asMYSQL_DOWNLOAD_HOME
- From the command prompt, "cd" to MYSQL_DOWNLOAD_HOME
(Some steps mentioned in the/INSTALL-BINARY file are skipped in this article, since they aren't relevant here)
- Run the scripts/mysql_install_db command from the command prompt:
Error:
Running that above command threw up the following error message:
That message looked strange because I was able to ping those hostnames and was sure that I had my hostname setup properly. So I decided to see why "usr/bin/resolveip" can't resolve those hostnames. So from the command prompt, I tried running the following command:
This threw up an error:
So obviously, /usr/bin/resolveip command doesn't exist at all. So why was the MySQL installation trying to use this non-existent command? I then decided to take a look at the scripts/mysql_install_db script under. The lines, in that script, from where this error is being thrown are as follows:
The important part from those lines are:
and
As can be seen the script tries to infer the location of "resolveip" command through the $extra_bindir variable. This variable gets set earlier in that script, based on various conditions. Some of the relevant lines are these:
In short, those lines check for the presence of "default" values for some variables like "basedir" in MySQL configuration files (from earlier installations) under some known locations like /etc/my.cnf or the /etc/mysql. Incidentally, I had one such file /etc/mysql/my.cnf with one of the lines being:
So effectively, MySQL ended up picking up "basedir" as /usr and ultimately the following lines in the script:
set extra_bindir to /usr/bin.
Now that explained why the MySQL installation ending up using /usr/bin/resolveip while resolving the hostname:
Solution:
For those who are just looking for a solution to get past this error, I'll just quickly explain what needs to be done. The scripts/mysql_install_db script allows for explicitly specifying the basedir to use during the installation. So the solution is to pass the as the value of basedir from the command prompt while running that script. Here's how you do it:
(Remember that we are running this command from theMYSQL_DOWNLOAD_HOME, so the relative path "." works fine for the basedir).
By passing the value for basedir we have now made sure that MySQL picks up the "resolveip" command from the correct location, which is MYSQL_DOWNLOAD_HOME/bin/resolveip. Yes, "resolveip" is indeed shipped as part of the MySQL download.
What's annoying about this error:
I earlier mentioned that I found this error annoying because of the misleading error message. As we saw, the real problem was that the installation script was trying to use an non-existent command (due to incorrect path). The reason why it used the incorrect path was mainly my fault, because I ignored a part in the INSTALL_BINARY file which mentioned:
*But* the error message should really have printed out a message which could probably have said:
This would have made it real easy for the user to fix the issue instead of trying to figure out what's wrong with their hostname.
Update: I've brought this up in the MySQL mailing list here http://lists.mysql.com/mysql/222638.
System details:
- Ubuntu 10.04 Operating System
- MySQL 5.1.x downloaded from the official site here http://dev.mysql.com/downloads/mysql/ and selected the "Compressed TAR Archive" (mysql-5.1.50-linux-i686-glibc23.tar.gz to be precise) under the "Linux - Generic" platform
Installation steps:
- Extracted the .tar.gz locally to /home/jpai/MySQL/mysql-5.1.50-linux-i686-glibc23. In the rest of this article, I'll refer to this path as
- From the command prompt, "cd" to
(Some steps mentioned in the
- Run the scripts/mysql_install_db command from the command prompt:
jpai@jpai-laptop:mysql-5.1.50-linux-i686-glibc23$ scripts/mysql_install_db
Error:
Running that above command threw up the following error message:
jpai@jpai-laptop:mysql-5.1.50-linux-i686-glibc23$ scripts/mysql_install_db Neither host 'jpai-laptop' nor 'localhost' could be looked up with /usr/bin/resolveip Please configure the 'hostname' command to return a correct hostname. If you want to solve this at a later stage, restart this script with the --force option
That message looked strange because I was able to ping those hostnames and was sure that I had my hostname setup properly. So I decided to see why "usr/bin/resolveip" can't resolve those hostnames. So from the command prompt, I tried running the following command:
jpai@jpai-laptop:~$ /usr/bin/resolveip --help
This threw up an error:
jpai@jpai-laptop:~$ /usr/bin/resolveip --help bash: /usr/bin/resolveip: No such file or directory
So obviously, /usr/bin/resolveip command doesn't exist at all. So why was the MySQL installation trying to use this non-existent command? I then decided to take a look at the scripts/mysql_install_db script under
# Check if hostname is valid
if test "$cross_bootstrap" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0
then
resolved=`$extra_bindir/resolveip $hostname 2>&1`
if test $? -ne 0
then
resolved=`$extra_bindir/resolveip localhost 2>&1`
if test $? -ne 0
then
echo "Neither host '$hostname' nor 'localhost' could be looked up with"
echo "$extra_bindir/resolveip"
echo "Please configure the 'hostname' command to return a correct"
echo "hostname."
echo "If you want to solve this at a later stage, restart this script"
echo "with the --force option"
exit 1
fi
echo "WARNING: The host '$hostname' could not be looked up with resolveip."
echo "This probably means that your libc libraries are not 100 % compatible"
echo "with this binary MySQL version. The MySQL daemon, mysqld, should work"
echo "normally with the exception that host name resolving will not work."
echo "This means that you should use IP addresses instead of hostnames"
echo "when specifying MySQL privileges !"
fi
fi
The important part from those lines are:
resolved=`$extra_bindir/resolveip $hostname 2>&1`
and
resolved=`$extra_bindir/resolveip localhost 2>&1`
As can be seen the script tries to infer the location of "resolveip" command through the $extra_bindir variable. This variable gets set earlier in that script, based on various conditions. Some of the relevant lines are these:
# Now we can get arguments from the groups [mysqld] and [mysql_install_db]
# in the my.cfg file, then re-run to merge with command line arguments.
parse_arguments `$print_defaults $defaults mysqld mysql_install_db`
parse_arguments PICK-ARGS-FROM-ARGV "$@"
# Configure paths to support files
if test -n "$srcdir"
then
basedir="$builddir"
bindir="$basedir/client"
extra_bindir="$basedir/extra"
mysqld="$basedir/sql/mysqld"
langdir="$srcdir/sql/share/english"
pkgdatadir="$srcdir/scripts"
scriptdir="$srcdir/scripts"
elif test -n "$basedir"
then
bindir="$basedir/bin"
extra_bindir="$bindir"
mysqld=`find_in_basedir mysqld libexec sbin bin`
if test -z "$mysqld"
then
cannot_find_file mysqld $basedir/libexec $basedir/sbin $basedir/bin
exit 1
fi
langdir=`find_in_basedir --dir errmsg.sys share/english share/mysql/english`
if test -z "$langdir"
then
cannot_find_file errmsg.sys $basedir/share/english $basedir/share/mysql/english
exit 1
fi
pkgdatadir=`find_in_basedir --dir fill_help_tables.sql share share/mysql`
if test -z "$pkgdatadir"
then
cannot_find_file fill_help_tables.sql $basedir/share $basedir/share/mysql
exit 1
fi
scriptdir="$basedir/scripts"
else
basedir="."
bindir="./bin"
extra_bindir="$bindir"
mysqld="./bin/mysqld"
pkgdatadir="./share"
scriptdir="./bin"
fi
In short, those lines check for the presence of "default" values for some variables like "basedir" in MySQL configuration files (from earlier installations) under some known locations like /etc/my.cnf or the /etc/mysql. Incidentally, I had one such file /etc/mysql/my.cnf with one of the lines being:
... basedir = /usr ...
So effectively, MySQL ended up picking up "basedir" as /usr and ultimately the following lines in the script:
... bindir="$basedir/bin" extra_bindir="$bindir" ...
set extra_bindir to /usr/bin.
Now that explained why the MySQL installation ending up using /usr/bin/resolveip while resolving the hostname:
resolved=`$extra_bindir/resolveip $hostname 2>&1`
Solution:
For those who are just looking for a solution to get past this error, I'll just quickly explain what needs to be done. The scripts/mysql_install_db script allows for explicitly specifying the basedir to use during the installation. So the solution is to pass the
jpai@jpai-laptop:mysql-5.1.50-linux-i686-glibc23$ scripts/mysql_install_db --basedir=.
(Remember that we are running this command from the
By passing the value for basedir we have now made sure that MySQL picks up the "resolveip" command from the correct location, which is
What's annoying about this error:
I earlier mentioned that I found this error annoying because of the misleading error message. As we saw, the real problem was that the installation script was trying to use an non-existent command (due to incorrect path). The reason why it used the incorrect path was mainly my fault, because I ignored a part in the INSTALL_BINARY file which mentioned:
Warning If you have previously installed a MySQL installation using your operating system native package management system, such as yum or apt-get, you may experience problems installing using a native binary. Make sure your previous MySQL previous installation has been removed entirely (using your package management system), and that any additional files, such as old versions of your data files, have also been removed. You should also check the existence of configuration files such as /etc/my.cnf or the /etc/mysql directory have been deleted.
*But* the error message should really have printed out a message which could probably have said:
"/usr/bin/resolveip" command not found. Make sure basedir (and other variables) point to the right location. Tip: resolveip can be located in the bin folder of MySQL download location.
This would have made it real easy for the user to fix the issue instead of trying to figure out what's wrong with their hostname.
Tuesday, July 27, 2010
EJB3.1 TimerService in JBoss AS 6.0.0.M4
For those of you, who have been waiting for more of EJB3.1 features in JBoss AS, here's some good news! JBoss AS 6.0.0.M4 which will be released in a day or two, introduces support for EJB3.1 Timer Service and EJB3.1 Asynchronous invocations. In this article, we'll see some examples on EJB3.1 timer service features.
Download JBoss AS:
Before, starting with the example, let's first download JBoss AS 6.0.0.M4. You can download it from here. After downloading the AS, start and stop it once to make sure it boots without any issues.
In the next steps we will see a simple EJB3.1 timerservice example (mainly the calendar expression support)
EJB3.1 Timer Service:
Note that the examples shown below are just for the sake of illustrating the usage of timerservice API and as such don't hold much meaning.
Let's consider a very simple stateless session bean which exposes a remote business interface view:
So in the example above, we have a TimerOps interface which is exposed as the remote view for the Scheduler Stateless session bean. The TimerOps interface allows scheduling timers based on a javax.ejb.ScheduleExpression. This ScheduleExpression is used to express calendar based timeout expressions. We will see more of it, later in this article.
Moving on to the Scheduler SLSB, you will notice that it expects the TimerService to be injected:
The injection of timer service into beans, requires no more than annotating that field with the @javax.annotation.Resource annotation. The bean will then use the injected timerservice to create and operate on the timers.
Let's look at the scheduleTask method in that bean:
It doesn't do much, actually. It first creates (an optional) javax.ejb.TimerConfig to pass during timer creation. The TimerConfig, is where you specify whether the timer has to be persistent and/or any additional Serializable "info" that needs to be associated with the Timer, so that it is available in the timeout callback method.
In our example, above, we set the timer to be persistent (that's the default anyway) and also set the "info" to the taskName that was passed. This can be any Serializable info. Here we are just passing around some dummy String, for the sake of demonstrating the API usage.
Then, we use the injected timerservice to create a calendar timer. A calendar timer is a Timer which is created based on a calendar schedule expression. A calendar schedule expression is represented by a ScheduleExpression which expresses a schedule based on the following attributes:
Please refer to the EJB3.1 spec for more details on ScheduleExpression.
So, for example, if we want to schedule a timer to fire every Monday at 3:30 in the morning, then we can create the following ScheduleExpression:
Okay, so let's back to our Scheduler bean now. This is where we create the timer in the bean:
So once the Scheduler bean's schedule method completes, the timer will be started (remember, timers are transactional, so the timer start waits for the transaction to complete). Once the timeout occurs for the timer, the server will invoke the timeout callback method on the bean. In our example, we have annotated our onTimeout() method as the timeout callback method (note the @Timeout annotation):
So that was our bean and its remote interface. Now let's take a quick look at our client code which looks up the bean and schedules the timer:
In the client code, we first lookup the TimerOps remote business view of the bean. We then create a calendar schedule which is expected to fire on every Monday at 3, 6 and 9 in the morning. We then use the bean to schedule the task. That's it. On Monday, every morning 3AM, 6AM and 9AM, you will see the timeout being fired.
What next?
The above example was just one part of the new features in EJB3.1 timer service. Here's another - let's assume that you want to avoid having an additional method on the bean just to create a timer. Let's say that you want a timer to be created and scheduled to fire every day at 8:30 in the morning, from the time the bean is deployed. EJB3.1 timer service allows that to be done! They are known as auto timers. Here's an example of the same (using annotations):
As you can see we have a Stateless (no-interface view) bean which just has this executeEveryDayAtEightThirty method. The important bit here is the @javax.ejb.Schedule annotation which is used on that method. The Schedule annotation is used to create auto timers. The server will look for methods on the bean with the @Schedule annotation and automatically create the timers when the bean is deployed. The schedule for the timers is passed through the annotation's attribute values. The method on which the @Schedule is used, is considered as the timeout callback method for that auto timer and will be invoked when the timeout occurs.
In our example above, we are creating an auto-timer which will fire every day at 8:30 in the morning and the executeEveryDayAtEightThirty method will be called.
Want some more?
Those were just some of the examples for EJB3.1 timer service. There's much more you can try out. For example, there's also the @Schedules (note that it's not the same as @Schedule), which can be used to create multiple auto-timers for the same timeout callback method. Furthermore, if you don't want to use annotations, you can as well use the deployment descriptors. We also haven't covered the other APIs on the TimerService or the Timer in these examples. We can go on and on, but let's keep this short for now.
But, do try out these new features and let us know if you run into any issues. Feel free to start a discussion about any issues around this, in our EJB3 User Forum or ping us on IRC.
Download JBoss AS:
Before, starting with the example, let's first download JBoss AS 6.0.0.M4. You can download it from here. After downloading the AS, start and stop it once to make sure it boots without any issues.
In the next steps we will see a simple EJB3.1 timerservice example (mainly the calendar expression support)
EJB3.1 Timer Service:
Note that the examples shown below are just for the sake of illustrating the usage of timerservice API and as such don't hold much meaning.
Let's consider a very simple stateless session bean which exposes a remote business interface view:
package org.jboss.ejb3.timerservice.example;
public interface TimerOps
{
/**
* Schedules a timer for the passedcalendarSchedule
*
* @param calendarSchedule The calendar expression based schedule
* @param taskName The name of the task, which will be passed an a info to the {@link Timer}
*
*/
void scheduleTask(ScheduleExpression calendarSchedule, String taskName);
}
package org.jboss.ejb3.timerservice.example;
import java.util.Date;
import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.ScheduleExpression;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
import org.jboss.ejb3.annotation.RemoteBinding;
@Stateless
@Remote (TimerOps.class)
@RemoteBinding (jndiBinding = "timerservice-example-scheduler-remote")
public class Scheduler implements TimerOps
{
@Resource
private TimerService timerService;
@Override
public void scheduleTask(ScheduleExpression calendarSchedule, String taskName)
{
// TimerConfig can be passed to the timer service, during timer creation,
// to specify whether the timer is persistent and also pass any additional
// Serializable info.
TimerConfig timerConfig = new TimerConfig();
// by default, timers are persistent. So we don't really have to
// set the persistence property on the TimerConfig. It's done here,
// just to demonstrate the usage
timerConfig.setPersistent(true);
// set the "info" to be passed to the timers
timerConfig.setInfo(taskName);
// Now, use the injected timerservice to create a timer instance,
// for the passed schedule and the timer config
Timer timer = this.timerService.createCalendarTimer(calendarSchedule, timerConfig);
// that's it, we are done. The timer is now created and started (on successful completion
// of this method). When the scheduled timeout occurs, a method in this bean which is marked
// as the timeout callback method will be invoked.
}
/**
* This method will be invoked by the server when a scheduled timeout occurs for timer(s)
* created through the timerservice corresponding to this bean.
*
* @param timer The {@link Timer} for which the timeout occurred
*/
@Timeout
private void onTimeout(Timer timer)
{
// do some task here. for now, let's just print out to System.out
System.out.println("Timeout method invoked at " + new Date() + " for bean " + this.getClass().getSimpleName());
}
}
So in the example above, we have a TimerOps interface which is exposed as the remote view for the Scheduler Stateless session bean. The TimerOps interface allows scheduling timers based on a javax.ejb.ScheduleExpression. This ScheduleExpression is used to express calendar based timeout expressions. We will see more of it, later in this article.
Moving on to the Scheduler SLSB, you will notice that it expects the TimerService to be injected:
@Resource
private TimerService timerService;
The injection of timer service into beans, requires no more than annotating that field with the @javax.annotation.Resource annotation. The bean will then use the injected timerservice to create and operate on the timers.
Let's look at the scheduleTask method in that bean:
@Override
public void scheduleTask(ScheduleExpression calendarSchedule, String taskName)
{
// TimerConfig can be passed to the timer service, during timer creation,
// to specify whether the timer is persistent and also pass any additional
// Serializable info.
TimerConfig timerConfig = new TimerConfig();
// by default, timers are persistent. So we don't really have to
// set the persistence property on the TimerConfig. It's done here,
// just to demonstrate the usage
timerConfig.setPersistent(true);
// set the "info" to be passed to the timers
timerConfig.setInfo(taskName);
// Now, use the injected timerservice to create a timer instance,
// for the passed schedule and the timer config
Timer timer = this.timerService.createCalendarTimer(calendarSchedule, timerConfig);
// that's it, we are done. The timer is now created and started (on successful completion
// of this method). When the scheduled timeout occurs, a method in this bean which is marked
// as the timeout callback method will be invoked.
}
It doesn't do much, actually. It first creates (an optional) javax.ejb.TimerConfig to pass during timer creation. The TimerConfig, is where you specify whether the timer has to be persistent and/or any additional Serializable "info" that needs to be associated with the Timer, so that it is available in the timeout callback method.
In our example, above, we set the timer to be persistent (that's the default anyway) and also set the "info" to the taskName that was passed. This can be any Serializable info. Here we are just passing around some dummy String, for the sake of demonstrating the API usage.
Then, we use the injected timerservice to create a calendar timer. A calendar timer is a Timer which is created based on a calendar schedule expression. A calendar schedule expression is represented by a ScheduleExpression which expresses a schedule based on the following attributes:
1) dayOfMonth : Specifies the day of month when the timeout should occur
Default Value = "*" (which means, any day of month)
Example values = Last, 1, 2, 31, 28 etc...
2) dayOfWeek : Specifies the day of week when the timeout should occur
Default Value = "*" (which means, any day of month)
Example values = Sun, Wed, 2, 7 etc...
3) hour : Specifies the hour when the timeout should occur
Default Value = "0"
Example values = 12, 23, 18, 2 etc...
4) minute : Specifies the minute when the timeout should occur
Default value = "0"
Example values = 10, 12, 35, 59 etc...
5) second : Specifies the second when the timeout should occur
Default Value = "0";
Example values = 10, 15, 20 etc...
6) month : Specifies the month when the timeout should occur
Default value = * (any month)
Example values = Jan, Mar, 4, 6 etc...
7) year : Specifies the year when the timeout should occur
Default value = * (any year)
Example values = 2010, 2020 etc...
Please refer to the EJB3.1 spec for more details on ScheduleExpression.
So, for example, if we want to schedule a timer to fire every Monday at 3:30 in the morning, then we can create the following ScheduleExpression:
ScheduleExpression everyMondayThreeThirty = new ScheduleExpression();
everyMondayThreeThirty.dayOfWeek("Mon").hour(3).minute(30);
Okay, so let's back to our Scheduler bean now. This is where we create the timer in the bean:
Timer timer = this.timerService.createCalendarTimer(calendarSchedule, timerConfig);
So once the Scheduler bean's schedule method completes, the timer will be started (remember, timers are transactional, so the timer start waits for the transaction to complete). Once the timeout occurs for the timer, the server will invoke the timeout callback method on the bean. In our example, we have annotated our onTimeout() method as the timeout callback method (note the @Timeout annotation):
/**
* This method will be invoked by the server when a scheduled timeout occurs for timer(s)
* created through the timerservice corresponding to this bean.
*
* @param timer The {@link Timer} for which the timeout occurred
*/
@Timeout
private void onTimeout(Timer timer)
{
// do some task here. for now, let's just print out to System.out
System.out.println("Timeout method invoked at " + new Date() + " for bean " + this.getClass().getSimpleName());
}
So that was our bean and its remote interface. Now let's take a quick look at our client code which looks up the bean and schedules the timer:
package org.jboss.ejb3.timerservice.example.client;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.ejb3.timerservice.example.*;
public class Client
{
public static void main(String[] args) throws Exception
{
Context ctx = new InitialContext();
// lookup the bean
TimerOps scheduler = (TimerOps) ctx.lookup("timerservice-example-scheduler-remote");
// create a schedule
// Let's say, we want to fire a timeout every Monday at 3, 6 and 9 in the morning
ScheduleExpression everyMonAtThreeSixAndNineAM = new ScheduleExpression();
everyMonAtThreeSixAndNineAM.dayOfMonth("Mon").hour("3,6,9");
// schedule our task
scheduler.scheduleTask(everyMonAtThreeSixAndNineAM, "Hello World Timer");
}
}
In the client code, we first lookup the TimerOps remote business view of the bean. We then create a calendar schedule which is expected to fire on every Monday at 3, 6 and 9 in the morning. We then use the bean to schedule the task. That's it. On Monday, every morning 3AM, 6AM and 9AM, you will see the timeout being fired.
What next?
The above example was just one part of the new features in EJB3.1 timer service. Here's another - let's assume that you want to avoid having an additional method on the bean just to create a timer. Let's say that you want a timer to be created and scheduled to fire every day at 8:30 in the morning, from the time the bean is deployed. EJB3.1 timer service allows that to be done! They are known as auto timers. Here's an example of the same (using annotations):
package org.jboss.ejb3.timerservice.example;
import javax.ejb.Schedule;
import javax.ejb.ScheduleExpression;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
import javax.naming.Context;
import javax.naming.InitialContext;
@Stateless
public class AutoScheduler
{
/**
* This method will be invoked every day at 8:30:00 in the morning
* @param timer The timer instance
*/
@Schedule (hour = "8", minute = "30")
private void executeEveryDayAtEightThirty(Timer timer)
{
// do some task here. for now, let's just print out to System.out
System.out.println("(Auto) timer method invoked at " + new Date() + " for bean " + this.getClass().getSimpleName());
}
}
As you can see we have a Stateless (no-interface view) bean which just has this executeEveryDayAtEightThirty method. The important bit here is the @javax.ejb.Schedule annotation which is used on that method. The Schedule annotation is used to create auto timers. The server will look for methods on the bean with the @Schedule annotation and automatically create the timers when the bean is deployed. The schedule for the timers is passed through the annotation's attribute values. The method on which the @Schedule is used, is considered as the timeout callback method for that auto timer and will be invoked when the timeout occurs.
In our example above, we are creating an auto-timer which will fire every day at 8:30 in the morning and the executeEveryDayAtEightThirty method will be called.
Want some more?
Those were just some of the examples for EJB3.1 timer service. There's much more you can try out. For example, there's also the @Schedules (note that it's not the same as @Schedule), which can be used to create multiple auto-timers for the same timeout callback method. Furthermore, if you don't want to use annotations, you can as well use the deployment descriptors. We also haven't covered the other APIs on the TimerService or the Timer in these examples. We can go on and on, but let's keep this short for now.
But, do try out these new features and let us know if you run into any issues. Feel free to start a discussion about any issues around this, in our EJB3 User Forum or ping us on IRC.
Subscribe to:
Posts (Atom)