<?xml version="1.0"?>

<!--
 * ========================================================================
 * 
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ========================================================================
-->

<document id="howto_ejb_j2eeri">

  <properties>
    <title>EJB Testing with J2EE RI</title>
  </properties>

  <body>

  <section title="Forewords">

    <p>
      This tutorial shows how to write test cases for unit testing
      EJB methods. The EJB used in this example is a simple Session Bean.
    </p>
    <p>
      This tutorial assumes the reader has already understood how to use
      Cactus to test Servlet. To test an EJB, you need to prepare a war to
      contain the cactus setting and test cases, and then prepare a jar of
      your ejb. You need to match the JNDI name in the ejb jar and the war.
    </p>

    <note>
      This is an EJB 1.1 example but the same principles are valid for
      EJB 2.0
    </note>

  </section>

  <section title="EJB Jar">

    <section title="Step 1: Prepare the Sample EJB">

      <p>
        The EJB used in this tutorial is a simple Session Bean with a method
        for converting Yen to Dollar.
      </p>

      <section title="EJB Remote">

<source><![CDATA[
package org.apache.cactus.sample.ejb;

import java.rmi.*;
import javax.ejb.*;

public interface Converter extends EJBObject
{
    public double convertYenToDollar(double theYenAmount) throws RemoteException;
}
]]></source>

      </section>

      <section title="EJB Home">

<source><![CDATA[
package org.apache.cactus.sample.ejb;

import java.rmi.*;
import javax.ejb.*;

public interface ConverterHome extends EJBHome
{
    public Converter create() throws RemoteException, CreateException;
}
]]></source>

      </section>

      <section title="EJB Bean">

<source><![CDATA[
package org.apache.cactus.sample.ejb;

import javax.ejb.*;

public class ConverterEJB implements SessionBean
{
    private SessionContext context;

    public double convertYenToDollar(double theYenAmount)
    {
        return theYenAmount / 100.0;
    }

    public ConverterEJB()
    {
    }

    public void ejbCreate() throws CreateException
    {
    }

    public void setSessionContext(SessionContext theContext)
    {
        this.context = theContext;
    }

    public void ejbActivate()
    {
    }

    public void ejbPassivate()
    {
    }

    public void ejbRemove()
    {
    }
}
]]></source>

      </section>

    </section>

    <section title="Step 2: Prepare EJB Deployment Descriptor (ejb-jar.xml)">

      <p>
        Prepare the standard EJB Deployment Descriptor for the Session EJB:
      </p>

<source><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>

<ejb-jar>
  <display-name>testejb</display-name>
  <enterprise-beans>
    <session>
      <description>Converter Session Bean</description>
      <display-name>Converter</display-name>
      <ejb-name>Converter</ejb-name>
      <home>org.apache.cactus.sample.ejb.ConverterHome</home>
      <remote>org.apache.cactus.sample.ejb.Converter</remote>
      <ejb-class>org.apache.cactus.sample.ejb.ConverterEJB</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
    </session>
  </enterprise-beans>
  <assembly-descriptor>
    <container-transaction>
      <method>
	<ejb-name>Converter</ejb-name>
	<method-intf>Remote</method-intf>
	<method-name>*</method-name>
      </method>
      <trans-attribute>NotSupported</trans-attribute>
    </container-transaction>
  </assembly-descriptor>
</ejb-jar>
]]></source>

    </section>

    <section title="Step 3: Prepare EJB Runtime (only valid for J2EE RI)">

<source><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>

<j2ee-ri-specific-information>
  <server-name></server-name>
  <rolemapping />

  <enterprise-beans>
    <ejb>
      <ejb-name>Converter</ejb-name>
      <jndi-name>ejb/Converter</jndi-name>
    </ejb>
  </enterprise-beans>

</j2ee-ri-specific-information>
]]></source>

    </section>

  </section>

  <section title="Cactus Web Application">

    <section title="Step 1: Prepare test code">

<source><![CDATA[
package org.apache.cactus.sample.ejb;

import javax.naming.*;
import javax.rmi.*;
import junit.framework.*;

import org.apache.cactus.*;

public class ConverterTest extends ServletTestCase
{
    private Converter converter;

    public ConverterTest(String name)
    {
        super(name);
    }

    public static Test suite()
    {
        return new TestSuite(ConverterTest.class);
    }

    public void setUp()
    {
        Context ctx = new InitialContext();
        ConverterHome home = (ConverterHome)
            PortableRemoteObject.narrow(ctx.lookup("java:comp/ejb/Converter"),
            ConverterHome.class);
        this.converter = home.create();
    }

    public void testConvert() throws Exception
    {
        double dollar = this.converter.convertYenToDollar(100.0);
        assertEquals("dollar", 1.0, dollar, 0.01);
    }
}
]]></source>

    </section>

    <section title="Step 2: Prepare Web Application Deployment Descriptor (web.xml)">

<source><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
    "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

<web-app>

    <servlet>
        <servlet-name>ServletRedirector</servlet-name>
        <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletRedirector</servlet-name>
        <url-pattern>/ServletRedirector</url-pattern>
    </servlet-mapping>

[...]

    <ejb-ref>
        <ejb-ref-name>ejb/Converter</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>org.apache.cactus.sample.ejb.ConverterHome</home>
        <remote>org.apache.cactus.sample.ejb.Converter</remote>
    </ejb-ref>

</web-app>
]]></source>

    </section>

    <section title="Step 3: Package Web Application">

      <p>
        Package the web application into a war and then deploy it. Please
        note that the <code>ejb-ref-name</code> in the deployment descriptor
        need to match with the JNDI name of the test EJB.
      </p>

    </section>

    <section title="Step 4: (Only valid to J2EE RI 1.2.1): War Runtime">

<source><![CDATA[
<j2ee-ri-specific-information>

  <server-name/>
  <rolemapping/>

  <web>
    <display-name>test</display-name>
    <context-root>test</context-root>
    <ejb-ref>
      <ejb-ref-name>ejb/Converter</ejb-ref-name>
      <jndi-name>ejb/Converter</jndi-name>
    </ejb-ref>
  </web>

</j2ee-ri-specific-information>
]]></source>

    </section>

    <section title="Step 5: Deploy">

      <p>
        You need to deploy the war and the <code>ejb-jar.xml</code> based on
        the deployment procedure of your servlet container and your ejb
        container.
      </p>

    </section>

  </section>

  </body>
</document>
