Title: Simple Stateless Example

<a name="SimpleStatelessExample-Overview"></a>
# Overview

<object width="400" height="250"><param name="movie"
value="http://www.youtube.com/v/aLx2jta96xU?fs=1&amp;hl=en_US"></param><param
name="allowFullScreen" value="true"></param><param name="allowscriptaccess"
value="always"></param><embed
src="http://www.youtube.com/v/aLx2jta96xU?fs=1&amp;hl=en_US"
type="application/x-shockwave-flash" allowscriptaccess="always"
allowfullscreen="true" width="400" height="250"></embed></object>


This example shows how to create a Stateless session EJB using annotations.
 As stated in the "JSR 220: Enterprise JavaBeansTM,Version 3.0 - EJB Core
Contracts and Requirements",


"Stateless session beans are session beans whose instances have no
conversational state. This means that all bean instances are equivalent
when they are not involved in servicing a client-invoked method. The term
'stateless' signifies that an instance has no state for a specific client."


What this means is quite simply that stateless beans are *shared*.  They do
in fact have state as you can assign values to the variables, etc. in the
bean instance.	The only catch is there are a *pool* of identical instances
and you are not guaranteed to get the exact same instance on every call. 
For each call, you get whatever instance happens to be available.  This is
identical to checking out a book from the library or renting a movie from
the video store.  You are essentially checking out or renting a new bean
instance on each method call.

With EJB 3.0, it's now possible to write stateless session bean without
specifying a deployment descriptor; you basically have to write just a
remote or local business interface, which is a plain-old-java-interface,
annotated with the @Remote or @Local annotation the stateless session bean
implementation, a plain-old-java-object which implements the remote or the
local business interface and is annotated with the @Stateless annotation



<a name="SimpleStatelessExample-TheCode"></a>
# The Code

In this example we develop a simple EJB 3 Stateless session EJB.  Every
stateless session bean implementation must be annotated using the
annotation *@Stateless* or marked that way in the ejb-jar.xml file.

Our Stateless bean has 2 business interfaces: CalculatorRemote, a remote
business interface, and CalculatorLocal, a local business interface.  A
minimum of one business interface is required.

<a name="SimpleStatelessExample-Bean"></a>
## Bean

In EJB 3.0 session beans do not need to implement the javax.ejb.SessionBean
interface.  You can simply annotate it as @Stateless if you want it to be a
stateless session bean.

Users of EJB 2.x may notice the bean actually implements the business
interfaces! In the prior version of EJB implementing the remote interface
(which derives from javax.ejb.EJBObject) in your bean was just not allowed.
Now there is no javax.ejb.EJBObject requirement, so implementing the
business interfaces is standard practice for EJB 3.0.

<a name="SimpleStatelessExample-Localbusinessinterface"></a>
## Local business interface

Local interfaces in EJB are *pass-by-reference* interfaces.  Meaning that
*normal java semantics* are used for passing arguments, return values and
exceptions.  A business local interface can be any plain java interface. 
There are no restrictions on the method arguments, return types, or throws
clauses.  

Unless specified otherwise, every interface your bean implements (and it's
parent class implements and so on) is considered to be a local business
interface.  You can use the *@Local* annotation to explicitly state that an
interface is a local interface, but this is not required.

You'll notice that in EJB 3.0 the Local Business Interface of a stateless
session bean does not need to extend from javax.ejb.EJBLocalObject and does
not need a javax.ejb.EJBLocalHome interface as they did in EJB 2.x and
prior.	Per the vocabulary of the EJB spec, interfaces that implement
javax.ejb.EJBLocalObject or javax.ejb.EJBLocalHome are considered Component
Interfaces and the plain java interface above is considered a Business
Interface.

<a name="SimpleStatelessExample-Remotebusinessinterface"></a>
## Remote business interface

Remote interfaces are *pass-by-value* interfaces.  Meaning that all method
parameters, return values, and exceptions are *serialized* on every call. 
The result is that you get a copy of the original object and not the
original object.  The advantage is of course that Remote interfaces can be
used to invoke an EJB across a network in a client-server fashion.  There
are no restrictions on the Remote interface itself, but there are on the
data passed in and out of the remote interface.  The *values* passed into a
method or returned from a method of a Remote interface *must be
serializable*.	It is fine for the method signature to be, for example,
"public Object myMethod(Object myParam)" as long as the *value* passed in
and returned implements *java.io.Serializable*.

As stated above, the Remote Business Interface of a bean can be any plain
old interface.	It does not need to extend javax.ejb.EJBObject, it does not
need a javax.ejb.EJBHome, the methods do not need to throw
javax.rmi.RemoteException, and the bean class *can* implement it!

At minimum the interface must be annotated with *@Remote* either in the
interface itself or in the bean class, or the interface must be declared
via <business-remote> in the ejb-jar.xml.

<a name="SimpleStatelessExample-Writingaunittestfortheexample"></a>
# Writing a unit test for the example

Writing an unit test for the stateless session EJb is quite simple. We need
just to write a setup method to create and initialize the InitialContext,
and then write our test methods

<a name="SimpleStatelessExample-setUp"></a>
## setUp

<a name="SimpleStatelessExample-Testthelocalbusinessinterface"></a>
## Test the local business interface

<a name="SimpleStatelessExample-Testtheremotebusinessinterface"></a>
## Test the remote business interface

Note that JNDI names for Java SE clients are not standardized by the EJB
spec.  This is unfortunate and something being addressed in EJB 3.1.  The
default schema that OpenEJB uses is ejbName + interfaceType (i.e. Local,
Remote, LocalHome, RemoteHome), so in our example "CalculatorImpl" +
"Local" and "CalculatorImpl" + "Remote".  You can in fact change this
default to be absolutely [anything you want](jndi-names.html)
 including interface class name, ejb class name, and more.

## CalculatorBean

    package org.superbiz.stateless.basic;

    import javax.ejb.Stateless;

    @Stateless
    public class CalculatorBean {

        public int add(int a, int b) {
            return a + b;
        }

        public int subtract(int a, int b) {
            return a - b;
        }

        public int multiply(int a, int b) {
            return a * b;
        }

        public int divide(int a, int b) {
            return a / b;
        }

        public int remainder(int a, int b) {
            return a % b;
        }
    }

## CalculatorTest

Our `CalculatorBean` can be easily tested using the `EJBContainer` API in EJB 3.1

    package org.superbiz.stateless.basic;

    import junit.framework.TestCase;

    import javax.ejb.embeddable.EJBContainer;

    public class CalculatorTest extends TestCase {

        private CalculatorBean calculator;

        /**
         * Bootstrap the Embedded EJB Container
         *
         * @throws Exception
         */
        protected void setUp() throws Exception {

            EJBContainer ejbContainer = EJBContainer.createEJBContainer();

            Object object = ejbContainer.getContext().lookup("java:global/simple-stateless/CalculatorBean");

            assertTrue(object instanceof CalculatorBean);

            calculator = (CalculatorBean) object;
        }

        /**
         * Test Add method
         */
        public void testAdd() {

            assertEquals(10, calculator.add(4, 6));
        }

        /**
         * Test Subtract method
         */
        public void testSubtract() {

            assertEquals(-2, calculator.subtract(4, 6));
        }

        /**
         * Test Multiply method
         */
        public void testMultiply() {

            assertEquals(24, calculator.multiply(4, 6));
        }

        /**
         * Test Divide method
         */
        public void testDivide() {

            assertEquals(2, calculator.divide(12, 6));
        }

        /**
         * Test Remainder method
         */
        public void testRemainder() {

            assertEquals(4, calculator.remainder(46, 6));
        }
    }

# Running

Running the example should generate output similar to the following

    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running org.superbiz.stateless.basic.CalculatorTest
    Apache OpenEJB 4.0.0-beta-1    build: 20111002-04:06
    http://tomee.apache.org/
    INFO - openejb.home = /Users/dblevins/examples/simple-stateless
    INFO - openejb.base = /Users/dblevins/examples/simple-stateless
    INFO - Using 'javax.ejb.embeddable.EJBContainer=true'
    INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
    INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
    INFO - Found EjbModule in classpath: /Users/dblevins/examples/simple-stateless/target/classes
    INFO - Beginning load: /Users/dblevins/examples/simple-stateless/target/classes
    INFO - Configuring enterprise application: /Users/dblevins/examples/simple-stateless
    INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
    INFO - Auto-creating a container for bean CalculatorBean: Container(type=STATELESS, id=Default Stateless Container)
    INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container)
    INFO - Auto-creating a container for bean org.superbiz.stateless.basic.CalculatorTest: Container(type=MANAGED, id=Default Managed Container)
    INFO - Enterprise application "/Users/dblevins/examples/simple-stateless" loaded.
    INFO - Assembling app: /Users/dblevins/examples/simple-stateless
    INFO - Jndi(name="java:global/simple-stateless/CalculatorBean!org.superbiz.stateless.basic.CalculatorBean")
    INFO - Jndi(name="java:global/simple-stateless/CalculatorBean")
    INFO - Jndi(name="java:global/EjbModule181871104/org.superbiz.stateless.basic.CalculatorTest!org.superbiz.stateless.basic.CalculatorTest")
    INFO - Jndi(name="java:global/EjbModule181871104/org.superbiz.stateless.basic.CalculatorTest")
    INFO - Created Ejb(deployment-id=CalculatorBean, ejb-name=CalculatorBean, container=Default Stateless Container)
    INFO - Created Ejb(deployment-id=org.superbiz.stateless.basic.CalculatorTest, ejb-name=org.superbiz.stateless.basic.CalculatorTest, container=Default Managed Container)
    INFO - Started Ejb(deployment-id=CalculatorBean, ejb-name=CalculatorBean, container=Default Stateless Container)
    INFO - Started Ejb(deployment-id=org.superbiz.stateless.basic.CalculatorTest, ejb-name=org.superbiz.stateless.basic.CalculatorTest, container=Default Managed Container)
    INFO - Deployed Application(path=/Users/dblevins/examples/simple-stateless)
    INFO - EJBContainer already initialized.  Call ejbContainer.close() to allow reinitialization
    INFO - EJBContainer already initialized.  Call ejbContainer.close() to allow reinitialization
    INFO - EJBContainer already initialized.  Call ejbContainer.close() to allow reinitialization
    INFO - EJBContainer already initialized.  Call ejbContainer.close() to allow reinitialization
    Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.068 sec

    Results :

    Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
