Sample of a Stateless Session Bean in EJB 3.0
This sample will demonstrate the following new features from EJB 3.0
- 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.
- Elimination of the requirement for home interfaces for session beans.
- Encapsulation of environmental dependencies and JNDI access through the use of annotations, dependency injection mechanisms, and simple lookup mechanisms.
- 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.
...
Code Block |
---|
| java |
---|
| java |
---|
borderStyle | solid |
---|
title | 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:
No Format |
---|
|
|- 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. This is generated by maven during the build and may be found in the ear or at calculator-stateless-ear/target/application.xml. The versions will vary depending on the source code version.
Code Block |
---|
| xml |
---|
| xml |
---|
borderStyle | solid |
---|
title | application.xml |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<?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.02-SNAPSHOT.war</web-uri>
<context-root>/calculator-stateless</context-root>
</web>
</module>
<module>
<ejb>calculator-stateless-ejb-2.02-SNAPSHOT.jar</ejb>
</module>
</application>
|
geronimo-applicationplan.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 applicationA Geronimo plan is not needed for standalone deployment of this application but is recommended to fix the module id. This example is completed by the car-maven-plugin in calculator-stateless-jetty. The dependencies are not actually needed for standalone deployment.
Code Block |
---|
| xml |
---|
| xml |
---|
borderStyle | solid |
---|
title | geronimo-applicationplan.xml |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.2">
<dep:environment <environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
<dep:moduleId>
<moduleId><dep:groupId>org.apache.geronimo.samples</dep:groupId>
<dep:artifactId>calculator-jetty</dep:artifactId>
<groupId>${pom.groupId}</groupId>
<dep:version>2.1.2</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
<artifactId>${pom.artifactId}</artifactId><dep:dependencies>
<dep:dependency>
<version>${version}</version>
<dep:groupId>org.apache.geronimo.configs</dep:groupId>
<dep:artifactId>jetty6</dep:artifactId>
<type>ear</type><dep:version>2.1.2</dep:version>
</moduleId>
<dep:type>car</dep:type>
</environment>dep:dependency>
<dep:dependency>
<module> <dep:groupId>org.apache.geronimo.configs</dep:groupId>
<web>calculator-stateless-war-${version}.war</web><dep:artifactId>jasper</dep:artifactId>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.2"><dep:version>2.1.2</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
<dep:dependency>
<context-root>/calculator-stateless</context-root> <dep:groupId>org.apache.geronimo.configs</dep:groupId>
<dep:artifactId>openejb</dep:artifactId>
</web-app>
<dep:version>2.1.2</dep:version>
</module> <dep:type>car</dep:type>
</application>
|
Installation instructions
...
dep:dependency>
<dep:dependency>
<dep:groupId>org.apache.geronimo.configs</dep:groupId>
<dep:artifactId>openjpa</dep:artifactId>
<dep:version>2.1.2</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
</dep:dependencies>
<dep:hidden-classes/>
<dep:non-overridable-classes/>
</dep:environment>
</application>
|