Tuesday, December 28, 2010

JBoss AS 6.0 Final released

JBoss AS 6.0.0.Final has just been released. The release notes are here and the download is available from the JBoss AS download page here.

I'll blog more about this in the days to come. For now, to summarize what's new in 6.0.0 Final - there have been numerous bug fixes for issues reported by the community. Furthermore from a EJB3.1 point of view, we now have EJB3.1 Embedded support and a far better support for EJB3.1 @Asynchronous functionality.

As usual, give it a try and feel free to ask any questions or report any issues, in our user forums:

JBoss AS user forum: http://community.jboss.org/en/jbossas?view=discussions
EJB3 user forum: http://community.jboss.org/en/ejb3?view=discussions

Monday, November 29, 2010

JBoss AS 6.0 CR1 released

JBoss AS 6.0 CR1 was released last week and I'm bit late on writing this blog :) I'll briefly summarize what 6.0 CR1 contains, mainly from EJB3.1 point of view.

Like I mentioned in my previous blog entry, this latest release of AS now has support for EJB3.1 spec mandated JNDI naming scheme for EJBs. It also contains various bug fixes in JBoss EJB3 implementation that were reported by the community in the previous versions of JBoss AS. We are now left with just a couple of EJB3.1 features - support for EJB3.1 Embedded and a full fledged support for EJB3.1 @Asynchronous invocations. These 2 features will make it to 6.0 Final version of JBoss AS, which is planned during December 2010.

Apart from EJB3.1, the other set of new features and bug fixes in 6.0 CR1 have been listed here. Shelly has blogged about this release and the upcoming 6.0 Final release here.

So go download the latest release and give it a try. As usual, feel free to report any issues (so that they get fixed in 6.0 Final) in our user forums. Some useful links are provided below:

JBoss AS Download page : http://www.jboss.org/jbossas/downloads.html

JBoss AS user forum : http://community.jboss.org/en/jbossas?view=discussions

JBoss EJB3 user forum : http://community.jboss.org/en/ejb3?view=discussions

JBoss AS JIRA (bug tracking system) : https://jira.jboss.org/browse/JBAS

Sunday, October 10, 2010

EJB3.1 Global JNDI Access - A portable jndi naming scheme for EJBs

Many of you, who have been using EJBs would know that one of the pain points, with respect to portability, is the JNDI names of the beans. As you all will be aware, prior to EJB3.1 spec, there wasn't a standard portable JNDI naming scheme for EJBs. Each application server had its own JNDI naming scheme, which would often mean that you either had to include a server specific deployment descriptor (jboss.xml for JBoss AS) or use annotations to override the JNDI names (for EJB3.0). So while migrating our project to some other application server, you almost always would end up with NameNotFoundException, if you forgot to configure/change the JNDI names to match the application server you are deploying to.

However, starting EJB3.1, the spec now mandates portable JNDI names for EJBs. The compliant application servers are now expected to bind the EJBs at some pre-defined portable JNDI names. Effectively, when you deploy the same EJB jar into a different compliant application server, you will no longer have to change/configure the JNDI names, if you use the portable JNDI names during lookup.

Syntax of portable JNDI names:

The EJB3.1 spec (section 4.4 "Global JNDI Access") explains the syntax of the portable JNDI names. It's actually more than a couple of lines, with examples. So quoting that section here would be a waste of space. Its better to just download the spec and read through it. But I'll just show some examples of the portable JNDI names, in the next section.

Example of the new JNDI naming scheme:

Let's assume you have the following Stateless EJB:

 
package org.myapp.ejb.impl;

@Stateless
@Remote(Echo.class)
@LocalBean
public class SimpleSLSB implements Echo
{
...
}


The SimpleSLSB exposes a remote business interface view and also (explicitly) marks the bean for the no-interface view. So this bean now has 2 views - the remote business interface view and the no-interface view.

Let's further assume that we are packaging this bean in a simple .jar file and deploying it to the application server. Let's name the jar file myejb3.jar.

As per the EJB3.1 spec, global jndi naming scheme, this bean will now be available at (all of the) following JNDI names:

java:global/myejb3/SimpleSLSB!org.myapp.ejb.impl.Echo
java:global/myejb3/SimpleSLSB!org.myapp.ejb.impl.SimpleSLSB
java:app/myejb3/SimpleSLSB!org.myapp.ejb.impl.Echo
java:app/myejb3/SimpleSLSB!org.myapp.ejb.impl.SimpleSLSB
java:module/SimpleSLSB!org.myapp.ejb.impl.Echo
java:module/SimpleSLSB!org.myapp.ejb.impl.SimpleSLSB



#1 above exposes the remote business interface view in the java:global namespace and #2 exposes the no-interface view (remember, we explicitly marked our bean as @LocalBean) in the java:global namespace. As can be seen, the JNDI name is composed of a namespace (for example java:global), a app/module name (for example myejb3), the bean name, which by default is the unqualified name of the bean implementation class (for example SimpleSLSB) and finally the fully qualified name of the business interface being exposed (for example, org.myapp.ejb.impl.Echo). In case of no-interface view, the final part of the JNDI name is the fully qualified name of the bean implementation class.

The rest of the JNDI names follow the same naming scheme, except that they are available in a different JNDI namespace. More details can be found in the EJB3.1 spec (section 4.4 "Global JNDI Access").

Support for EJB3.1 global JNDI names in JBoss AS:

The current JBoss AS trunk supports this new JNDI naming scheme. So the upcoming JBoss AS 6.0.0.CR1 release will have support for this feature. However, if you want to try it out before JBoss AS 6.0.0.CR1 is released, then you can download the nightly build of JBoss AS from here and give it a try.

Reporting issues:

If you have any questions or run into issue while testing this, then feel free to bring it up in our EJB3 user forum.

Saturday, September 25, 2010

JBoss AS 6.0.0.M5 released

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

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 as MYSQL_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:

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 . The lines, in that script, from where this error is being thrown are as follows:
# 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 as the value of basedir from the command prompt while running that script. Here's how you do it:
jpai@jpai-laptop:mysql-5.1.50-linux-i686-glibc23$ scripts/mysql_install_db --basedir=.



(Remember that we are running this command from the  MYSQL_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:

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.

Update: I've brought this up in the MySQL mailing list here http://lists.mysql.com/mysql/222638.

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:


 
package org.jboss.ejb3.timerservice.example;

public interface TimerOps
{

/**
* Schedules a timer for the passed calendarSchedule
*
* @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.

Wednesday, May 05, 2010

JBoss AS 6.0.0.M3 released

6.0.0.M3 version of JBoss AS has just been released. You can find the release notes here and you can download the server from the JBoss AS downloads page

This release in addition to bug fixes and other new features, includes support for EJB3.1 Singleton beans. You can find the details and an example here. So it's time to try out this new feature and report any issues in our EJB3 user forums here!

Ofcourse, any JBoss AS specific issues can be discussed in the JBoss AS user forum.

Tuesday, May 04, 2010

JBoss getting started, DZone RefCard published

JBoss EAP5/AS5 DZone RefCard has just been published today. It gives you a quick overview of JBoss server installation, deployment, management and its clustering capabilities.

The RefCard has been authored by Scott Marlow, Shelly McGowan, Brian Stansberry, Len DiMaggio and me. You can get a copy of it from here.

Sunday, April 18, 2010

Eclipse Logback Plugin with JBoss AS

Recently in one of the forum threads an user asked how to use Logback Eclipse Plugin along with slf4j logging framework in JBoss AS. Having been tired of all those logging frameworks out there, I wasn't really too interested in looking at the details. But during this weekend, I had this sudden urge of trying out some simple application on which I wouldn't have to spend too much time or energy. So I decided to see what it takes to get the Logback Eclipse Plugin running against JBoss AS. So here's what it takes (well, nothing much actually - around half an hour or less):

Pre-requisites:

- JBoss Application Server 5.1.0 : Since this is the latest stable version, I decided to use this for testing. I don't see any reason why it shouldn't work against other version of the AS (4.x or 6.x).

- Latest release of slf4j library (1.5.11 at the time of writing this article) : JBoss AS-5 (and even AS-6) already ships with the slf4j jar in its lib folder. But since this is just another third party library, each user app should be able to package their own version of the jar within the app (and apply the usual classloading isolation configurations to the app). You can download slf4j from here

- Logback library version 0.9.9 : The logback library can be downloaded from the download site here. The only important thing to remember is to download version 0.9.9 (and *not* the latest one), because the latest versions of that plugin does not work due to a bug. Version 0.9.9 can be found here

- Eclipse IDE : I am currently on 3.4.1 Eclipse. I don't think the version of Eclipse would matter for this application.

- Logback Eclipse Plugin : The details of this plugin can be found here. It includes information on how to configure the plugin for Eclipse and where to download it from. At the time of writing this article, I found the plugin download here


Sample application:

Now that we have the required libraries and the setup ready, the next step is to write a simple application which makes use of slf4j logging framework backed by logback, to log some messages. Since this article is mainly meant as a quick start of getting logback Eclipse plugin working against JBossAS, I decide to use a simple servlet which does nothing more than log some messages.

The servlet looks like this:
 
package org.myapp.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleServlet extends HttpServlet
{

private static Logger slf4jLogger = LoggerFactory.getLogger(SimpleServlet.class);

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
slf4jLogger.info("******************************************");
slf4jLogger.info("***Hello World from a simple servlet***");
slf4jLogger.info("***Let's try out some logging messages***");
slf4jLogger.info("******************************************");

slf4jLogger.debug("This is DEBUG message");
slf4jLogger.info("This one is INFO message");
slf4jLogger.warn("Let's also send out a WARN message");
slf4jLogger.error("Well, sometimes we run into ERROR messages too");
try
{
throw new Exception("Intentional exception for demo");
}
catch (Exception e)
{
slf4jLogger.error("Error with stacktrace", e);
}
slf4jLogger.info("******************************************");
slf4jLogger.info("***That's it, folks!!!***");
slf4jLogger.info("******************************************");

}

}

It uses slf4j LoggerFactory to create a Logger and then use that logger to write out some log messages at different log levels. That's it.

The web.xml, just maps this servlet to some URL:



<?xml version="1.0" encoding="UTF-8"?>

<web-app>
<display-name>Logback example for JBossAS</display-name>

<servlet>
<servlet-name>SimpleServlet</servlet-name>
<servlet-class>org.myapp.servlet.SimpleServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>SimpleServlet</servlet-name>
<url-pattern>invokeServlet</url-pattern>
</servlet-mapping>

</web-app>


Then there's jboss-web.xml for classloading configuration:


<jboss-web>

<class-loading>
<loader-repository>
org.myapp:classloader=logback-example
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
</class-loading>
</jboss-web>


And finally, the important one, the logback.xml file which is responsible for configuring the consolePlugin:



<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="true">

<consolePlugin />

</configuration>


Yes, that's all you need in the logback.xml to get it working. More details can be found in its documentation here. The above config file creates a SocketAppender which uses port 4321 (by default). The Logback Plugin in Eclipse (also by default) connects to this 4321 to receive the log messages (when they are logged).

Note: The debug="true" in that logback.xml is just to show some debug messages when logback is reading that config file. You can remove that attribute, if you don't need such messages.

So now that we have these files ready, we just need to create a deployable application to test it out. I decided to use a .war file in this demo. You can even use a .ear file. I won't get into the details of how to create the .war file. Use your favourite build tool or an IDE to generate the .war file. The final .war should look like this:


myapp.war
|
|--- WEB-INF
| |
| |--- web.xml
| |--- jboss-web.xml
| |
| |--- lib
| | |
| | |--- logback-classic-0.9.9.jar
| | |--- logback-core-0.9.9.jar
| | |--- slf4j-api-1.5.11.jar
| |
| |
| |--- classes
| | |
| | |--- logback.xml
| | |
| | |--- org
| | | |--- myapp
| | | | |--- servlet
| | | | | |--- SimpleServlet.class



Note that the logback.xml is placed in .war/WEB-INF/classes folder because logback looks for that file in the classpath. Also notice the contents of .war/WEB-INF/lib folder - those are the jars that you'll have to package in your application. logback-classic-0.9.9.jar and logback-core-0.9.9.jar can be found in the logback download (which you did in the pre-requisites section). slf4j-api-1.5.11.jar can be found in the slf4j download.

Place this .war file in JBOSS_HOME/server/< servername>/deploy folder and start the server. Also open Eclipse IDE (if it's not already open) and open the "Logback View". Since we haven't yet logged anything from our application, the view will be empty (see image below).



So now let's invoke our servlet which logs the messages. As shown in the web.xml, I have mapped the servlet to the "invokeServlet" URL. So from my web browser, I access http://localhost:8080/myapp/invokeServlet

That's it, the servlet starts logging the messages and in the "Logback View" of Eclipse you will see the logged messages (see image below).



You have now successfully configured Logback Eclipse Plugin to work against JBoss AS. Did not take long to get it working!

Tuesday, April 06, 2010

EJB3.1 Singleton Bean support now available in JBoss AS trunk

For those, who have been waiting for EJB3.1 Singleton bean support in JBoss AS, here's some good news. This week, we updated the AS trunk to include support for singleton beans. JBoss AS 6.0.0 M3 will be released in the next few weeks. In the meantime, those of you who want to try out this feature, can follow the instructions here

Feel free to report any issues, in our EJB3 user forum

Wednesday, February 17, 2010

JBoss AS 6.0.0.M2 released

JBoss AS 6.0.0.M2 has been released yesterday. This is the second milestone release of the JBoss AS-6 series. You can download it from here.

Brian's blog contains details about what this new release contains. From the EJB3.1 point of view, this release contains the initial EJB3.1 support. See this wiki for more details.

Other than the new features that have been added to 6.0.0.M2, you will also notice that this new version boots faster than the earlier 5.x and 6.0.0.M1 versions. There have been numerous (valid) complaints about slow boot time with AS-5.x and 6.0.0.M1. Although there have been performance improvements after 5.1.0 release, they weren't too noticeable. However, in this version of AS, there have been numerous performance fixes within the JBoss Microcontainer (JBoss MC) project and various other places which ultimately has resulted in a better boot time for JBoss AS. For those who believe in numbers, here's the boot time comparison on my local system:

JBoss AS-5.1.0 "default" server config:


21:02:56,538 INFO [ServerImpl] JBoss (Microcontainer) [5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221053)] Started in 42s:792ms


JBoss AS 6.0.0.M1 "default" server config:


21:08:42,775 INFO [AbstractServer] JBossAS [6.0.0.M1 (build: SVNTag=JBoss_6_0_0_M1 date=200911281333)] Started in 36s:156ms


JBoss AS 6.0.0.M2 "default" server config:


15:22:01,708 INFO [org.jboss.bootstrap.impl.base.server.AbstractServer] JBossAS [6.0.0.20100216-M2 (build: SVNTag=JBoss_6_0_0_20100216-M2 date=20100216)] Started in 22s:311ms


So a boot time improvement of 20 seconds from 5.1.0 and 14 seconds from 6.0.0.M1.

One important thing that users must be aware is that, JBoss AS 6.0.0.M2 has introduced the notion of lazy deployment of applications. While working on improving the boot time of AS, it was noticed that the admin-console (JBOSS_HOME/server/< servername>/deploy/admin-console.war) adds almost 25 to 30 seconds to the boot time of the AS. Obviously this isn't good. Furthermore, not many developers really use admin-console, atleast not very frequently while developing and testing their application. So deploying the admin-console (and any other such application) by default isn't of any value for such users. So it was decided that the notion of lazy deployments would be introduced.

To put it in simple terms - although the admin-console.war, jmx-console.war and jbossws-console.war will be shipped by default in the AS, they will no longer be *deployed* by default. The first access to any of these applications is going to deploy them. The complete set of details can be found in this forum thread. So in AS 6.0.0.M2, you will notice that these applications have now been moved to JBOSS_HOME/common/deploy folder. Note that, the admin-console is still a bit of heavy beast during deployment - you will see a slow response during admin-console deployment (so first access to this application is going to be slow). But this will no longer add to the boot time. There are plans to further improve the boot time of the AS in the next coming M3 release. So this is not the end of boot time performance improvements, but definitely a good start!

So, go download the newly released version and try it out! Let us know of any issues you run into in our AS user forum. And if you have run into any EJB3(.1) issues, or have any questions around it, then feel free to ping us on #jboss-ejb3 (irc.freenode.net) or even vist our EJB3 user forum

Wednesday, January 20, 2010

EJB3.1 initial support in JBoss AS

Good news for those waiting for EJB3.1 support in JBoss AS :) The upcoming JBoss AS 6.0.0.M2 will have the initial EJB3.1 support. The AS release is scheduled a few weeks from now. Last weekend we added some of the EJB3.1 support to the JBoss AS trunk. This includes the no-interface view for EJBs and also deployment of EJBs through .war files. So in it's present state, the AS trunk has these EJB3.1 features available.

Those of you who want to try this out and provide feedback/bug reports etc... please follow this thread in the EJB3 user forum. Good luck and let us know, in the forums, how it goes!