You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 33 Next »

Sample of a Stateless Session Bean in EJB 3.0

This sample will demonstrate the following new features from EJB 3.0

  1. Elimination of the requirement for EJB component interfaces for session beans. The required business interface for a session bean can be a plain Java interface rather than an EJBObject, EJBLocalObject, or java.rmi.Remote interface.
  2. Elimination of the requirement for home interfaces for session beans.
  3. Encapsulation of environmental dependencies and JNDI access through the use of annotations, dependency injection mechanisms, and simple lookup mechanisms.
  4. Introduction of Java metadata annotations to be used as an alternative to deployment descriptors.

Calculator Implementation

Calculator.java: A stateless session bean that implements a simple java interface instead of an EJB component interface like EJBObject, EJBLocalObject or java.rmi.Remote. By annotating this class as a @Stateless session there is no need for a deployment descriptor to describe it separately. This class implements both a local and remote business interface, namely CalculatorLocal and CalculatorRemote.

Calculator.java
package org.apache.geronimo.samples.slsb.calculator;

import javax.ejb.Stateless;

@Stateless
public class Calculator implements CalculatorRemote, CalculatorLocal {

	public int sum(int add1, int add2) {
		return add1+add2;
	}

	public int multiply(int mul1, int mul2) {
		return mul1*mul2;
	}

}

CalculatorLocal.java: Since this is a local business interface, it is optional that the coder marks this class with a @Local annotation. A business interface which is not annotated with @Local or @Remote is assumed to be Local.

CalculatorLocal.java
package org.apache.geronimo.samples.slsb.calculator;

public interface CalculatorLocal {

	public int sum(int add1, int add2);

	public int multiply(int mul1, int mul2);
}

CalculatorRemote.java: Since this is a remote business interface, it must be annotated with the @Remote annotation.

CalculatorRemote.java
package org.apache.geronimo.samples.slsb.calculator;

import javax.ejb.Remote;

@Remote
public interface CalculatorRemote {

	public int sum(int add1, int add2);

	public int multiply(int mul1, int mul2);

}

CalculatorServlet.java: This is a servlet to process the form on the jsp page. It uses the stateless session bean Calculator to do some computation and returns the result. Note that CalculatorLocal is being annotated with the @EJB annotation. The ejb container will route every request to different bean instances. Note: a stateful session bean must be declared at the type level, whereas a stateless session bean may be declared at any level.

CalculatorServlet.java
package org.apache.geronimo.samples.calculator;

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.geronimo.samples.slsb.calculator.CalculatorLocal;

public class CalculatorServlet extends HttpServlet {

    @EJB
    private CalculatorLocal calc = null;

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

        try {
            String firstNumber = req.getParameter("firstNumber");
            String secondNumber = req.getParameter("secondNumber");
            String operation = req.getParameter("operation");

            int firstInt = (firstNumber == null) ? 0 : Integer.valueOf(firstNumber).intValue();
            int secondInt = (secondNumber == null) ? 0 : Integer.valueOf(secondNumber).intValue();

            if ( "multiply".equals(operation) ) {
                req.setAttribute("result", calc.multiply(firstInt, secondInt));
            }
            else if ( "add".equals(operation) ) {
                req.setAttribute("result", calc.sum(firstInt, secondInt));
            }

            System.out.println("Result is " + req.getAttribute("result"));

            getServletContext().getRequestDispatcher("/sample-docu.jsp").forward(req, resp);

        }
        catch ( Exception e ) {
            e.printStackTrace();
            throw new ServletException(e);
        }
    }
}

Deployment Plans

The structure of the deployable should look like the following:

|- calculator-stateless-ear-2.0-SNAPSHOT.ear
   |- META-INF
      |- application.xml
      |- geronimo-application.xml
   |- calculator-stateless-ejb-2.0-SNAPSHOT.jar
   |- calculator-stateless-war-2.0-SNAPSHOT.war

application.xml: The JAR file is referenced to provide the functionality of this deployable. The WAR file is referenced in order to show the usage of this deployable through a web based interface. The context-root is set to be /calculator-stateless so that the URL for this application will be http://<hostname>:<port>/calculator-stateless.

application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
             version="5">
    <description>Geronimo Sample EAR for Stateless Session</description>
    <display-name>Geronimo Sample EAR for Stateless Session</display-name>
    <module>
        <web>
            <web-uri>calculator-stateless-war-2.0-SNAPSHOT.war</web-uri>
            <context-root>/calculator-stateless</context-root>
        </web>
    </module>
    <module>
        <ejb>calculator-stateless-ejb-2.0-SNAPSHOT.jar</ejb>
    </module>
</application>

geronimo-application.xml: Information about the project (e.g. module's unique identification, any dependencies) is described inside the <environment> tag. In this case, there are no dependencies so there is nothing to be listed. However, it is a good idea to give this module some sort of unique identification, so that it can later be referenced by some other deployable application.

geronimo-application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.2">

    <environment xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
        <moduleId>
            <groupId>${pom.groupId}</groupId>
            <artifactId>${pom.artifactId}</artifactId>
            <version>${version}</version>
            <type>ear</type>
        </moduleId>
    </environment>
    
    <module>
        <web>calculator-stateless-war-${version}.war</web>
        <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.2">
            <context-root>/calculator-stateless</context-root>
        </web-app>
    </module>
    
</application>

Installation instructions

  1. Checkout the source code of this sample from SVN:

    svn checkout http://svn.apache.org/repos/asf/geronimo/samples/trunk/samples/calculator-stateless-pojo

  2. Build the source code by executing mvn install site command. That will create calculator-stateless-ear-2.0-SNAPSHOT.ear file in the current directory.
  3. Go to the $geronimo_home/bin directory and start the geronimo server.
  4. Deploy the calculator-stateless-ear-2.0-SNAPSHOT.ear file using the console by clicking on this link. The userid/password for the console is system/manager. Or to deploy using the command line, use the following command

    deploy --user system --password manager deploy <path to the ear file>

  5. Click on this url http://localhost:8080/calculator-stateless. Read the documentation there.

    Once you go the sample application, click on the "source" tab in the top right hand corner to see the source code. Click on the "javadoc" tab to see the javadocs.

  • No labels