Creating a Stateless Session Bean

I l @ ve RuBoard

Now you can move on to actually creating your first EJB. To begin, create a new subdirectory called ejb in your com/bfg source hierarchy. You're going to move the logic that computes sales tax into a bean called Cart . Start by writing the remote interface (see Listing 17.1), which extends EJBObject . There's not much to it really ”it just declares the calling parameters for the computeTax call and specifies that it throws RemoteException , as all EJB beans must.

By convention, if a bean implements a functionality called Foo , the remote interface is called Foo , the home interface is called FooHome , and the enterprise bean is called FooBean .

Listing 17.1 Cart.java
 package com.bfg.ejb.cart; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Cart extends EJBObject {    public double computeTax(double amount, String state) throws RemoteException; } 

Next, you will write the home bean (see Listing 17.2), which extends EJBHome . Again, it's just a stub that doesn't even define the methods for the class; it just tells how to create a remote interface object.

Listing 17.2 CartHome.java
 package com.bfg.ejb.cart; import java.io.Serializable; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface CartHome extends EJBHome {     Cart create() throws RemoteException, CreateException; } 

Finally, you write the bean itself (see Listing 17.3), which extends SessionBean . In addition to the computeTax method, which implements the actual logic, you need to implement a bunch of empty methods to handle EJB functionality that you don't care about in this example.

Listing 17.3 CartBean.java
 package com.bfg.ejb.cart; import java.rmi.RemoteException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; public class CartBean implements SessionBean {     public double computeTax(double amount, String state)     {           if ((state != null) &&               (state.compareTo("MA") < 0)) {               return amount * 0.05D;           } else {               return amount * 0.10D;           }     }    public void ejbCreate()    {}    public void ejbPostCreate()    {}    public void ejbRemove()    {}    public void ejbActivate()    {}    public void ejbPassivate()    {}    public void setSessionContext(SessionContext sc)    {} } 

To deploy the EJB, you need to package it appropriately for JBoss. This means building a custom .jar file with some special configuration files, which are written in XML. The first of these is the ejb-jar.xml file (see Listing 17.4), which describes the bean.

Listing 17.4 ejb-jar.xml
 <?xml version="1.0" encoding="UTF-8"?> <ejb-jar>      <description>BFG EJB Overkill Example</description>      <display-name>BFG Overkill</display-name>      <enterprise-beans>        <session>          <ejb-name>Cart</ejb-name>          <home>com.bfg.ejb.cart.CartHome</home>          <remote>com.bfg.ejb.cart.Cart</remote>          <ejb-class>com.bfg.ejb.cart.CartBean</ejb-class>          <session-type>Stateless</session-type>          <transaction-type>Bean</transaction-type>        </session>      </enterprise-beans> </ejb-jar> 

As you can see, in this simple case, the ejb-jar.xml file simply defines the name of the bean and the description text. It also declares which classes to use for the home, remote, and bean; and states that it's stateless.

You also should create a jboss.xml file (see Listing 17.5), which sets up the JNDI mapping between the bean and its JNDI name.

Listing 17.5 jboss.xml
 <?xml version="1.0" encoding="UTF-8"?> <jboss>   <enterprise-beans>     <session>       <ejb-name>Cart</ejb-name>       <jndi-name>bfg/Cart</jndi-name>     </session>   </enterprise-beans> </jboss> 

To deploy an application, you need to set up a .jar with the following structure:

 C:\CARTAPP\bfg>jar tf bfgejb.jar META-INF/ META-INF/ejb-jar.xml META-INF/jboss.xml com/ com/bfg/ com/bfg/ejb/ com/bfg/ejb/cart/ com/bfg/ejb/cart/CartHome.class com/bfg/ejb/cart/Cart.class com/bfg/ejb/cart/CartBean.class META-INF/MANIFEST.MF 

This is copied into the jboss deploy directory, where it is automatically incorporated into the EJB environment. Listing 17.6 shows the Ant scripting to do it.

Listing 17.6 Ant Scripting for JBoss
 <property name="jbossdir" value="/jboss/Jboss-2.4.3/"/> . . .   <target name="makejboss" depends="compile">      <jar jarfile="bfgejb.jar">         <fileset dir="ejb" includes="**/*"/>         <fileset dir="src" includes="com/bfg/ejb/**/*.class"/>      </jar>   </target>   <target name="deployjboss" depends="makejboss">      <copy todir="${jbossdir} /deploy">         <fileset dir="." includes="bfgejb.jar"/>      </copy>   </target> 

The makejboss target bundles up the ejb subdirectory (which has a single subdirectory called META-INF) and the ejb-specific classes into a .jar. The deployjboss target places it in the right directory under the JBoss hierarchy to be deployed.

When you do a deployjboss , the .jar file is copied into JBoss's deployment directory. JBoss automatically takes note of the new file, unpacks it, and makes it available for use. Listing 17.7 shows the results of a deployment.

Listing 17.7 Deploying bdgejb.jar
 [AutoDeployer] Auto deploy of file:/C:/jboss/JBoss-2.4.3/deploy/bfgejb.jar [J2EE Deployer Default] Deploy J2EE application: file:/C:/jboss/JBoss-2.4.3/deploy/bfgejb. graphics/ccc.gif jar [J2eeDeployer] Create application bfgejb.jar [J2eeDeployer] install EJB module bfgejb.jar [Container factory] Deploying:file:/C:/jboss/JBoss-2.4.3/tmp/deploy/Default/bfgejb.jar [Verifier] Verifying file:/C:/jboss/JBoss-2.4.3/tmp/deploy/Default/bfgejb.jar/ejb1001.jar [Container factory] Deploying Cart [ContainerManagement] Initializing [ContainerManagement] Initialized [ContainerManagement] Starting [ContainerManagement] Started [Container factory] Deployed application: file:/C:/jboss/JBoss-2.4.3/tmp/deploy/ Default/bfgejb.jar  [J2EE Deployer Default] J2EE application: file:/C:/jboss/JBoss-2.4.3/deploy/bfgejb.jar graphics/ccc.gif is deployed. 

Now you can write a Tomcat JSP page to test your new bean, shown in Listing 17.8.

Listing 17.8 TestTax.jsp
 <%@ page import="javax.naming.*" %> <%@ page import="javax.naming.directory.*" %> <%@ page import="java.util.Hashtable" %> <%@ page import="com.bfg.ejb.cart.CartHome" %> <%@ page import="com.bfg.ejb.cart.Cart" %> <%@ page import="javax.rmi.PortableRemoteObject" %> <% Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,      "org.jnp.interfaces.NamingContextFactory"); env.put(Context.PROVIDER_URL,      "jnp://localhost:1099"); env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); DirContext ctx = new InitialDirContext(env); Object ref = ctx.lookup("bfg/Cart"); CartHome home = (CartHome) PortableRemoteObject.narrow(ref, CartHome.class); Cart cart = home.create(); %>     Tax on .00 in MA is <%= cart.computeTax(5.00D, "MA") %><BR>     Tax on .00 in CA is <%= cart.computeTax(5.00D, "CA") %><BR> 

First, the code needs to get a handle on the context for your bean so that it can request a copy. This sets up a connection to an EJB server running on your local machine.

Now you can get a reference to your bean by using the name that you set up with the jboss.xml file.

From the reference, you can get a copy of your Home object. You then use the Home object to get a copy of the remote interface.

Finally, you can use the stub to invoke the methods remotely, resulting in the correct results (see Figure 17.1).

Figure 17.1. Computing tax the hard way.

graphics/17fig01.jpg

I l @ ve RuBoard


MySQL and JSP Web Applications. Data-Driven Programming Using Tomcat and MySQL
MySQL and JSP Web Applications: Data-Driven Programming Using Tomcat and MySQL
ISBN: 0672323095
EAN: 2147483647
Year: 2002
Pages: 203
Authors: James Turner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net