Chapter 22. Exercises for Chapter 4

Exercise 4.1: A Simple Entity Bean

The Cabin EJB demonstrates basic CMP 2.0 capability for a simple entity bean mapped to a single table. The following sections outline the steps necessary to build, deploy, and execute the Cabin EJB example. Please note that because you’re using JBoss’s default embedded database, you don’t need to configure the database or create tables. The code you’ll see here mirrors the example code provided in Chapter 4 of the EJB book.

Start Up JBoss

Start up JBoss as described in the JBoss Installation and Configuration chapter at the beginning of this workbook.

Initialize the Database

The database table for this exercise will automatically be created in JBoss’s default database, HypersonicSQL, when the EJB JAR is deployed.

Build and Deploy the Example Programs

Perform the following steps:

  1. Open a command prompt or shell terminal and change to the ex04_1 directory created by the extraction process.

  2. Set the JAVA_HOME and JBOSS_HOME environment variables to point to where your JDK and JBoss 4.0 are installed. Examples:

    Windows: C:workbookex04_1> set JAVA_HOME=C:jdk1.4.2 C:workbookex04_1> set JBOSS_HOME=C:jboss-4.0
    Unix: $ export JAVA_HOME=/usr/local/jdk1.4.2 $ export JBOSS_HOME=/usr/local/jboss-4.0
  3. Add ant to your execution path. Ant is the build utility

    Windows: C:workbookex04_1> set PATH=..antin;%PATH%
    Unix: $ export PATH=../ant/bin:$PATH
  4. Perform the build by typing ant. Ant uses build.xml to figure out what to compile and how to build your JARs.

If you need to learn more about the Ant utility, visit the Ant project at the Jakarta web site at http://jakarta.apache.org/ant/index.html.

Ant compiles the Java source code, builds the EJB JAR, and deploys the JAR simply by copying it to JBoss’s deploy directory. If you are watching the JBoss console window, you will notice that JBoss automatically discovers the EJB JAR once it has been copied into the deploy directory, and automatically deploys the bean.

Another particularly interesting thing about building EJB JARs is that there is no special EJB compilation step. Unlike other servers, JBoss does not generate code for client stubs. Instead, it has a lightweight mechanism that creates client proxies when the EJB JAR is deployed, accelerating the development and deployment cycle.

Deconstructing build.xml

The build.xml file provided for each workbook exercise gives the Ant utility information about how to compile and deploy your Java programs and EJBs. The following build tasks can be executed by typing ant taskname :

  • The default task (just typing ant without a task name) compiles the code, builds the EJB JAR, and deploys the JAR into JBoss. The deployment procedure is just a simple copy into the JBoss deploy directory.

  • ant compile compiles all the Java source files.

  • ant clean removes all .class and .jar files from the working directory and undeploys the JAR from JBoss by deleting the file from JBoss’s deploy directory.

  • ant clean.db provides you with a clean copy of the HypersonicSQL database used throughout the exercises. This task works only with HypersonicSQL.

  • run.client_xxx runs a specific example program. Each exercise in this book will have a run.client rule for each example program.

Warning

clean.db can be used only when JBoss is not running.

Here’s a breakdown of what is contained in build.xml.

<project name="JBoss" default="ejbjar" basedir=".">

The default attribute defines the default target that ant will run if you type only ant on the command line. The basedir attribute tells Ant what directory to run the build in:

  <property environment="env"/>
  <property name="src.dir" value="${basedir}/src/main"/>
  <property name="src.resources" value="${basedir}/src/resources"/>
  <property name="jboss.home" value="${env.JBOSS_HOME}"/>
  <property name="build.dir" value="${basedir}/build"/>
  <property name="build.classes.dir" value="${build.dir}/classes"/>

All the properties defined above are variables that Ant will use throughout the build process. You can see that the JBOSS_HOME environment variable is pulled from the system environment and other directory paths defined:

  <path id="classpath">
        <fileset dir="${jboss.home}/client">
            <include name="**/*.jar"/>
        </fileset>
    <pathelement location="${build.classes.dir}"/>
    <pathelement location="${basedir}/jndi"/>
  </path>

To compile and run the example applications in this workbook, add all the JARS in $JBOSS_HOME/client to the Java classpath. Also notice that build.xml inserts the ${basedir}/jndi directory into the classpath. A jndi.properties file in this directory enables the example programs to find and connect to JBoss’s JNDI server:

  <property name="build.classpath" refid="classpath"/>

  <target name="prepare" >
    <mkdir dir="${build.dir}"/>
    <mkdir dir="${build.classes.dir}"/>
  </target>

The prepare target creates the directories where the Java compiler will place compiled classes:

  <target name="compile" depends="prepare">
    <javac srcdir="${src.dir}"
           destdir="${build.classes.dir}"
           debug="on"
           deprecation="on"
           optimize="off"
           includes="**">
            <classpath refid="classpath"/>
    </javac>
  </target>

The compile target compiles all the Java files under the src/main directory. Notice that it depends on the prepare target; prepare will run before the compile target is executed:

<target name="ejbjar" depends="compile">
  <jar jarfile="build/titan.jar">
    <fileset dir="${build.classes.dir}">
          <include name="com/titan/cabin/*.class"/>
    </fileset>
    <fileset dir="${src.resources}/">
        <include name="**/*.xml"/>
    </fileset>
   </jar>
   <copy file="build/titan.jar"
         todir="${jboss.home}/server/default/deploy"/>
</target>

The ejbjar target creates the EJB JAR file and deploys it to JBoss simply by copying it to JBoss’s deploy directory:

<target name="run.client_41a" depends="ejbjar">
  <java classname="com.titan.clients.Client_1" fork="yes" dir=".">
    <classpath refid="classpath"/>
  </java>
</target>

<target name="run.client_41b" depends="ejbjar">
  <java classname="com.titan.clients.Client_2" fork="yes" dir=".">
    <classpath refid="classpath"/>
  </java>
</target>

The run.client_xxx targets are used to run the example programs in this chapter:

<target name="clean.db">
  <delete dir="${jboss.home}/server/default/db/hypersonic"/>
</target>

The clean.db target cleans the default database used by JBoss for the example programs in this book. Remember, you can only use it when JBoss is not running:

<target name="clean">
  <delete dir="${build.dir}"/>
  <delete file="${jboss.home}/server/default/deploy/titan.jar"/>
</target>
</project>

The clean target removes compiled classes and undeploys the EJB JAR from JBoss by deleting the JAR file in the deploy directory.

Examine the JBoss-Specific Files

You do not need any JBoss-specific files to write a simple EJB. For an entity bean as simple as the Cabin EJB, JBoss creates the appropriate database tables within its embedded database Hypersonic SQL by examining the ejb-jar.xml deployment descriptor.

Tip

In later chapters, you will learn how to map entity beans to different data sources and pre-existing database tables using JBoss-specific CMP deployment descriptors.

By default, JBoss uses the <ejb-name> from the bean’s ejb-jar.xml deployment descriptor for the JNDI binding of the bean’s home interface. If you do not like this default, you can override it in a jboss.xml file. Clients use this name to look up an EJB’s home interface. For this example, CabinEJB is bound to CabinHomeRemote.

jboss.xml

<jboss>
  <enterprise-beans>
    <entity>
       <ejb-name>CabinEJB</ejb-name>
       <jndi-name>CabinHomeRemote</jndi-name>
    </entity>
  </enterprise-beans>
</jboss>

Examine and Run the Client Applications

Two example programs implement the sample clients provided in the EJB book:

Client_1.java

Creates a single Cabin bean, populates each of its attributes, then queries the created bean with the primary key.

Client_2.java

Creates 99 additional Cabins with a variety of different data that will be used in subsequent exercises.

Client_1.java

package com.titan.clients;

import com.titan.cabin.CabinHomeRemote;
import com.titan.cabin.CabinRemote;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import java.rmi.RemoteException;

public class Client_1 
{
   public static void main(String [] args) 
   {
      try 
      {
         Context jndiContext = getInitialContext( );
         Object ref = jndiContext.lookup("CabinHomeRemote");
         CabinHomeRemote home = (CabinHomeRemote)
            PortableRemoteObject.narrow(ref,CabinHomeRemote.class);   
         CabinRemote cabin_1 = home.create(new Integer(1));
         cabin_1.setName("Master Suite");
         cabin_1.setDeckLevel(1);
         cabin_1.setShipId(1);
         cabin_1.setBedCount(3);
             
         Integer pk = new Integer(1);
            
         CabinRemote cabin_2 = home.findByPrimaryKey(pk);
         System.out.println(cabin_2.getName( ));
         System.out.println(cabin_2.getDeckLevel( ));
         System.out.println(cabin_2.getShipId( ));
         System.out.println(cabin_2.getBedCount( ));

      } 
      catch (java.rmi.RemoteException re){re.printStackTrace( );}
      catch (javax.naming.NamingException ne){ne.printStackTrace( );}
      catch (javax.ejb.CreateException ce){ce.printStackTrace( );}
      catch (javax.ejb.FinderException fe){fe.printStackTrace( );}
   }

   public static Context getInitialContext( ) 
      throws javax.naming.NamingException 
   {
      return new InitialContext( );
   }
}

The getInitialContext( ) method creates an InitialContext with no properties. Because no properties are set, the Java library that implements InitialContext searches the classpath for the file jndi.properties. Each example program in this workbook will have a jndi directory that contains a jndi.properties file. You will be executing all example programs through Ant, and it will set the classpath appropriately to refer to this properties file.

Run the Client_1 application by invoking ant run.client_41a at the command prompt. Remember to set your JBOSS_HOME and PATH environment variables.

The output of Client_1 should look something like this:

C:workbookex04_1>ant run.client_41a
Buildfile: build.xml

prepare:

compile:

ejbjar:

run.client_41a:
     [java] Master Suite
     [java] 1
     [java] 1
     [java] 3

Client_1 adds a row to the database representing the Cabin bean and does not delete it at the conclusion of the program. You cannot run this program more than once unless you stop JBoss, clean the database by invoking the Ant task clean.db and restarting JBoss. Otherwise, you will get the following error:

run.client_41a:
     [java] javax.ejb.DuplicateKeyException: Entity with primary key 1 already exists
     [java]     at org.jboss.ejb.plugins.cmp.jdbc.JDBCCreateEntityCommand.
execute(JDBCCreateEntityCommand.java:160)
     [java]     at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.
createEntity(JDBCStoreManager.java:633)
     [java]     at org.jboss.ejb.plugins.CMPPersistenceManager.
createEntity(CMPPersistenceManager.java:253)
     [java]     at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.
createEntity(CachedConnectionInterce
...
     [java]     at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.
java:92)
     [java]     at org.jboss.proxy.TransactionInterceptor.
invoke(TransactionInterceptor.java:77)
     [java]     at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.
java:80)
     [java]     at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:
175)
     [java]     at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:82)
     [java]     at $Proxy0.create(Unknown Source)
     [java]     at com.titan.clients.Client_1.main(Client_1.java:22)

Run the Client_2 application by invoking ant run.client_41b at the command prompt. Remember to set your JBOSS_HOME and PATH environment variables.

The output of Client_2 should look something like this:

run.client_41b:
     [java] PK=1, Ship=1, Deck=1, BedCount=3, Name=Master Suite
     [java] PK=2, Ship=1, Deck=1, BedCount=2, Name=Suite 100
     [java] PK=3, Ship=1, Deck=1, BedCount=3, Name=Suite 101
     [java] PK=4, Ship=1, Deck=1, BedCount=2, Name=Suite 102
     [java] PK=5, Ship=1, Deck=1, BedCount=3, Name=Suite 103
     [java] PK=6, Ship=1, Deck=1, BedCount=2, Name=Suite 104
     [java] PK=7, Ship=1, Deck=1, BedCount=3, Name=Suite 105
     [java] PK=8, Ship=1, Deck=1, BedCount=2, Name=Suite 106
     ...
     [java] PK=90, Ship=3, Deck=3, BedCount=3, Name=Suite 309
     [java] PK=91, Ship=3, Deck=4, BedCount=2, Name=Suite 400
     [java] PK=92, Ship=3, Deck=4, BedCount=3, Name=Suite 401
     [java] PK=93, Ship=3, Deck=4, BedCount=2, Name=Suite 402
     [java] PK=94, Ship=3, Deck=4, BedCount=3, Name=Suite 403
     [java] PK=95, Ship=3, Deck=4, BedCount=2, Name=Suite 404
     [java] PK=96, Ship=3, Deck=4, BedCount=3, Name=Suite 405
     [java] PK=97, Ship=3, Deck=4, BedCount=2, Name=Suite 406
     [java] PK=98, Ship=3, Deck=4, BedCount=3, Name=Suite 407
     [java] PK=99, Ship=3, Deck=4, BedCount=2, Name=Suite 408
     [java] PK=100, Ship=3, Deck=4, BedCount=3, Name=Suite 409

Like Client_1, this example creates rows in the database and does not delete them when it finishes. Client_2 can be executed only once without causing DuplicateKey exceptions.

Managing Entity Beans

Every EJB in JBoss is deployed and managed as a JMX MBean. You can view and manage EJBs deployed within JBoss through your web browser by accessing the JMX management console available at http://localhost:8080/jmx-console/ (Figure 22-1).

The JMX management console

Figure 22-1. The JMX management console

Click on the jndiName=CabinHomeRemote,service=EJB link shown in Figure 22-1. Entity beans have two management functions. You can flush the entity bean’s cache or view the number of cached objects for it. To flush, click on the flushCache button. To view the number of cached beans, click on the getCacheSize button (Figure 22-2).

Managing entity beans from the console

Figure 22-2. Managing entity beans from the console

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.254.44