GlassFish Project - Simple Enterprise JavaBeansTM (EJB) 3.0 Stateful Session Bean Example 

New to GlassFish | Community Guidelines | Downloads | FAQ | How-Tos


This is a very simple EJB 3.0 Stateful Session Bean with a Remote business interface.  

Click here to get the ZIP file with the complete example.

Contact us at with any comments or questions.

Business Interface

The Stateful Session bean has a Remote business interface with two business methods : one for setting an ID, and one for retrieving it.  

package ejb30;
import javax.ejb.Remote;

public interface Sful {

    public void setId(String id);

    public String getId();


Note that unlike prior versions of EJB, the Remote interface is not required to extend java.rmi.Remote and its business methods are not required to throw java.rmi.RemoteException.

The business interface is designated as a remote business interface via the @javax.ejb.Remote annotation.

Note that there is no Home interface.  The Home interface is not required in EJB 3.0 simplified API.

Stateful Session Bean Class

Here's the bean implementation :

package ejb30;
import javax.ejb.Stateful;

public class SfulBean implements Sful {

    private String myId = "unknown";

    public void setId(String id) {
        myId = id;

    public String getId() {
        return myId;

@javax.ejb.Stateful is a component-defining annotation that designates this class as the bean class for a Stateful Session Bean.  

Note that all callback methods are optional in EJB 3.0, so it is not necessary to define an ejbCreate method.  

Deployment Descriptor

The good news is the deployment descriptor is no longer required!!!  The two java files above are sufficient to completely describe this stateful session bean.  

Application Client

Here's a Java EE Application Client that accesses the Stateful Session Bean using the @EJB annotation and dependency injection :

package ejb30;
import javax.ejb.EJB;

public class SfulAppClient {

    private static Sful sful;

    public static void main(String args[]) {

        System.out.println("Sful id = " + sful.getId());


The @EJB annotation tells the container that this component has a dependency on a business interface of an EJB.  At initialization time, the Application Client container will inject the variable "sful" with a reference to a new Stateful Session bean.   There's no JNDI lookup or casting required.

Note that the Java EE 5 specification requires that annotations within Application Client classes be static since the entry point for the application is the static main() method.  

Standalone Java Client

Here's an example of a plain Java client that runs outside of a Java EE container.  In this case, it does a global JNDI lookup since dependency injection is not available outside of a Java EE component.  

package ejb30;
import javax.naming.InitialContext;

public class SfulJavaClient {

    public static void main(String args[]) {

        try {

            InitialContext ic = new InitialContext();
            Sful sful = (Sful) ic.lookup("ejb30.Sful");
            System.out.println("Sful id = " + sful.getId());

        } catch(Exception e) {



SUN App Server Specific Deployment Configuration

There is no need to define any SUN App Server-specific deployment descrpitors (e.g. sun-ejb-jar.xml, sun-application-client.xml) for this example.   The JNDI name for the Remote Stateful Session bean will default to the fully-qualified class name of its Remote business interface  : ejb30.Sful.    The Application Client's Remote @EJB dependency will be resolved to the same value since its business interface type is also ejb30.Sful.  

Running the example

Use the following steps to build and execute the test.

  1. Set the glassfish.home property within build.xml.
  2. Set JAVA_HOME to point to a JDK 1.5 (or later) installation.
  3. ant build
  4. ant deploy
  5. ant run  

This will execute the Application Client and produce the following output :

Sful id = duke

Other Targets