Showing posts with label ejb31. Show all posts
Showing posts with label ejb31. Show all posts

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

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

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.