h5. Overview
JBoss AS 6.0.0.M3 which was released on May 5th 2010, introduces support for EJB3.1 Singleton beans.
h5. What to download and how to use
You can download JBoss AS 6.0.0.M3 from [here|http://www.jboss.org/jbossas/downloads.html]. After downloading the AS, start and stop it once to make sure it boots without any issues.
The next step would be to deploy a EJB3.1 Singleton bean into this server.
h5. EJB3.1 Singleton bean:
Note that the examples shown below are just for the sake of illustrating the usage of singleton beans and as such don't hold much meaning.
Let's deploy a very simple singleton bean which exposes a remote view:
{code:java}
package org.jboss.ejb3.singleton.example;
public interface Counter
{
void incrementCount();
void decrementCount();
int getCount();
}
{code}
{code:java}
package org.jboss.ejb3.singleton.example;
import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Singleton;
import org.jboss.ejb3.annotation.RemoteBinding;
@Singleton
@Remote(Counter.class)
@RemoteBinding (jndiBinding = "SimpleCounterRemoteJNDIName")
public class SimpleCounter implements Counter
{
// we use a calculator to increment/decrement the count
@EJB
private Calculator calculator;
// Maintains the current count
private int count;
@Override
public int getCount()
{
return this.count;
}
@Override
public void incrementCount()
{
this.count = this.calculator.add(this.count, 1);
}
@Override
public void decrementCount()
{
this.count = this.calculator.subtract(this.count, 1);
}
}
{code}
{code:java}
package org.jboss.ejb3.singleton.example;
import javax.ejb.Singleton;
@Singleton
public class Calculator
{
public int add(int a, int b)
{
return a + b;
}
public int subtract(int a, int b)
{
return a - b;
}
}
{code}
So in the example above, we have a Counter interface which is exposed as the remote view for the SimpleCounter Singleton bean. Notice that the SimpleCounter class is marked with @Singleton annotation:
{code:java}
@Singleton
@Remote(Counter.class)
@RemoteBinding (jndiBinding = "SimpleCounterRemoteJNDIName")
public class SimpleCounter implements Counter
{
...
{code}
The SimpleCounter internally uses a Calculator to do the increment and decrement operations. As you can see, the Calculator is being injected into the SimpleCounter by using a @EJB annotation:
{code:java}
// we use a calculator to increment/decrement the count
@EJB
private Calculator calculator;
{code}
If you look at the Calculator class, you will notice that it is a singleton bean with a no-interface view:
{code:java}
@Singleton
public class Calculator
{
...
{code}
So effectively, in this example, we have 2 singleton beans. One is exposing a remote view and the other is exposing a no-interface view.
Now package all these classes into a .jar and deploy it to the server which you downloaded earlier. That's it! You now have the beans deployed on the server. The next step is to write a simple client which access the Counter to perform the operations. In this example, let's use a standalone java class which through its main() method, looks up the remote view of the SimpleCounter and invokes the operations. Here's the client:
{code:java}
package org.jboss.ejb3.singleton.example.client;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.ejb3.singleton.example.Counter;
public class Client
{
public static void main(String args[]) throws Exception
{
Context ctx = new InitialContext();
// lookup the counter bean
Counter counter = (Counter) ctx.lookup("SimpleCounterRemoteJNDIName");
System.out.println("Initial count is " + counter.getCount());
// let's increment once
counter.incrementCount();
System.out.println("Count after increment is " + counter.getCount());
// now let's just look up the counter once more
// and see whether the incremented state is still maintained (it should be!)
Counter oneMoreCounter = (Counter) ctx.lookup("SimpleCounterRemoteJNDIName");
// should be 1
System.out.println("Count from another counter is " + oneMoreCounter.getCount());
// now let's decrement
oneMoreCounter.decrementCount();
// should be 0
System.out.println("Count after decrementing is " + counter.getCount());
}
}
{code}
In the client code, we first lookup the SimpleCounter singleton bean and try out a couple of operations through it. We then again lookup the same singleton bean and try out some more operations on it. Remember that since it's a singleton bean, all these operations will finally end up being called on the same singleton bean instance. So effectively, you will have a single state irrespective of the proxy instance on which you are invoking the operations.
h5. What should I try next?
The above example was just to get you started with EJB3.1 Singleton beans. Try out the singleton beans within your own applications 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|http://community.jboss.org/community/ejb3] or ping us on [IRC|http://www.jboss.org/ejb3/chat.html]. The more issues you find now, the better - because we can get some of them fixed before AS 6.0.0.M3 is released.
h5. I have some tutorial for singleton beans, Can I contribute?
Similar to our other EJB3 tutorials, we are going to include a tutorial for singleton beans. Infact, the example that is posted here in the wiki, can perhaps be just added as a tutorial in SVN. If anyone of you wants to contribute a different tutorial and a chapter in our guide, then feel free to let us know - either through the forums or IRC.
h5. Known issues:
Currently there are a couple of known-issues in the singleton bean implementation:
1) PostConstruct/PreDestroy are not invoked in a transactional context [EJBTHREE-2070|https://jira.jboss.org/jira/browse/EJBTHREE-2070]
2) The @DependsOn for a Singleton bean is not yet implemented
Comments