Stateless beans are used in the case when the process or action can be completed in one go. In this case, object state will not be preserved in a series of linked invocation. Each invocation of bean will be unique in itself in a Stateless Session Bean. A stateless session bean in represented by @Stateless annotation.

Here is an example of Simple Stateless Session Bean:

StatelessBean.java

As can be seen in the code, @Stateless defines a simple POJO as a Stateless Session bean.

The above gives a very high level idea of what is a stateless session bean and how is it implemented using EJB3 annotations. While working with examples we will try to make you understand stateless session beans in-depth.

Stateless Session Bean Sample

This sample application will take you through the basics of Stateless Session Bean. This application will demonstrate how annotations like @Stateless, @Resource, @PostConstruct, @PreDestroy are used in an EJB3 application.

The application walks through a authentication page, where the user has to authenticate to move to the resource page of Apache Geronimo. In case of a new user, the user has to go through the registration process. Later the user will be directed to login page again once the registration is done. In the login page the bean class will check for the username and password entered by the user against a database.

Basically a Stateless Session EJB is used whenever there is a single step process and maintaining a session is obsolete. In this sample the user registration form is a one step process and hence we have used stateless session bean for its implementation. The login page is a misnomer and should not be considered as an implementation for stateless session EJB. This is because once logged in you have to maintain the session and stateless session beans are not meant to maintain the session.

To run this tutorial, as a minimum you will be required to have installed the following prerequisite software.

Details on installing eclipse are provided in the Development environment section.
This tutorial is organized in the following sections:

Creating a Stateless Session EJB project

Right click under the Project Explorer and Create an EJB project as shown.

On the next screen give the project name as StatelessSessionEJB.

Right click on ejbModule and create a new Interface RegisterBeanRemote.

On the New Java Interface window give the package name as statelessejb and Interface name as RegisterBeanRemote.

Populate the RegisterBeanRemote interface with the following code.

RegisterBeanRemote.java

In the above code @Remote is a metadata annotation which marks the interface to be a Remote Interface. Metadata annotations are used to declare a class, interface or functions to have particular attributes. In this case the interface is marked to be a Remote Interface.

Right click on StatelessSessionEJB project and create a new class RegisterBean as shown in the figure.

Populate the class RegisterBean with the following data:

RegisterBean.java

Lets try to understand this code.

The very first line has an annotation @Stateless which declares the POJO to be a Stateless Session Bean. This annotation tells the container that the class is a Stateless Session Bean class. The container now automatically takes care of the various services like pooling, thread safety, transactions and so on.

The second line suggests that the bean class implements the remote interface. Every EJB application has to have at least one interface. In this case we are having a remote interface.

Next we have the @Resource(name="jdbc/userds") annotation which suggests jdbc/userds datasource being injected on to EJB. This is called dependency injection. The main idea behind dependency injection is that a component should call the resource through interfaces. This in turn will create a loosely coupled architecture between component and resource. Dependency injection is actually JNDI lookup in reverse order. In JNDI lookup the Bean looks up the resources itself and that is why it has to be hardcoded in the bean code itself whereas in Dependency Injection the Container reads the Bean and finds out what resources are required by the bean class. Later it injects the resources at runtime. How to create jdbc/userds datasource is discussed in the next section.

Next interesting part is the @PostConstruct annotation. This annotation is used for lifecycle callbacks. A lifecycle callback method is used by container to inform the bean class of the state transitions in the bean lifecycle. @PostConstruct annotation is used once a bean instance is created. In our example we have our bean instance created and Dependency injected. Later @PostConstruct callback is invoked and a connection to the datasource is established.

Next we have the register function which is used to populate the database USERINFO with user information. This function uses PreparedStatement to query the database.

Next is the verify function which is used for the authentication of user credentials.

@PreDestroy is again a lifecycle callback which suggests to release the resources before the bean is destroyed.

Warning

Due to some limitations in Geronimo Eclipse Plugin the generated deployment plan(openejb-jar.xml) does not have the correct namespace. Replace the existing namespace as shown in the figure with the following
<openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.2" xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pkgen="http://www.openejb.org/xml/ns/pkgen-2.0" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.2" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2">

Creating a datasource using Administrative Console

Once in the welcome page. In console navigation, Under Services, Select Database Pools.

On the next screen, Create a new database pool using Geronimo database pool wizard.

On the next screen give the name as suggested in the figure. This will initiate the process to create a Derby Embedded XA datasource.

Select the Driver jar and give the database name as userdbs (Remember this is the database we created in the previous step). The rest of fields can be set to default.

Select Deploy to deploy the connector plan.

Once done you can see the Database Pool jdbc/userds listed in the available database pools.

Creating application client

Create a new dynamic Web Project with the name ApplicationClient.

Right click on WebContent and create the following login.jsp:

login.jsp

This form is the login page for our application. Once the user enters his/her credentials, these are passed to another jsp passCredentials.jsp (checkout the action in the form tag) to verify the authenticity of user credentials. In case the user is new he has to go through the registration process. This statement <a href="http://localhost:8080/ApplicationClient/register.jsp">NewUser</a> is used to route the user to registration page.

passCredentials.jsp

<%!boolean i; %> is a declaration for a global variable. The other part is a scriptlet which does a JNDI lookup to the remote interface. Later the user credentials are passed to verify function. In case the credentials are correct user is routed to the resources page else he is redirected to login page to re-login.

Why is the lookup name RegisterBeanRemote??

This will be explained in the deploy an run section

resources.jsp

This is the final page of the application which displays the various resources.

register.jsp

This page is the registration page. Once th user fills up the form and press Submit a valform() function is called which validates the field username and password. In case any of them is empty an alert is send which suggests empty fields in the form. If all is fine passVariables.jsp is called.

passVariables.jsp

In this page the fields are retrieved from register.jsp and the register function in the bean class is called to populate the database.
The code <meta http-equiv="Refresh" content="5;URL=http://localhost:8080/ApplicationClient/login.jsp"> suggests to wait for 5 seconds and then move to login.jsp

index.jsp

Few more configurations

In the EJB Project. Under META-INF, edit openejb-jar.xml and add the following

datasource dependency

Finally the openejb-jar.xml will look like this

openejb-jar.xml

Where did the above dependencies come from??

To make the datasource visible to EJB we need to add a dependency to the EJB deployment plan that is openejb-jar.xml. The above element can be obtained automatically from Geronimo Database Pool wizard. Select usage against the database pool jdbc/userds

In the WEB Project. Under WEB-INF, Edit geronimo-web.xml and add the following

EJB dependency

Finally the geronimo-web.xml will look like this

geronimo-web.xml

Right click on the ApplicationClient Project and select properties. Select Java Build Path->Projects. Click Add and add Stateless Session EJB. This is required for the compilation of the Client code.

Deploy and Run

warning

Due to limitation with Geronimo Eclipse Plugin, you will have to export the Stateless Session EJB project and Web Application project as a jar and war respectively.

Export the projects to your local disk as StatelessSessionEJB.jar and ApplicationClient.war.