Chapter 29. Exercises for Chapter 12

Exercise 12.1: JMS as a Resource

This exercise is entirely based on the beans implemented in Exercise 11.2. You’ll modify the TravelAgent EJB so it publishes a text message to a JMS topic when it completes a reservation.

You’ll learn how to create a new JMS topic in JBoss, and configure your bean to use JMS as a resource. You’ll also build a client application that will subscribe to this topic and display any published message. To complete new reservations, you’ll use one of the client applications created for the preceding example.

Start Up JBoss

If JBoss is already running there is no reason to restart it.

Initialize the Database

Because the exercise uses the ProcessPayment EJB used in recent exercises, the database must contain the PAYMENT table. The createdb and dropdb Ant targets, Java code, and clients here have been borrowed from Exercise 11.1.

If you haven’t already dropped the PAYMENT table after running the examples in Exercise 11.2, do so now by running the dropdb Ant target.

C:workbookex12_1>ant dropdb
Buildfile: build.xml

prepare:

compile:

dropdb:
     [java] Looking up home interfaces..
     [java] Dropping database table...

BUILD SUCCESSFUL

Then re-create the PAYMENT database table by running the createdb Ant target

C:workbookex12_1>ant createdb
Buildfile: build.xml

prepare:

compile:

ejbjar:

createdb:
     [java] Looking up home interfaces..
     [java] Creating database table...

On the JBoss console, the following lines are displayed:

INFO  [STDOUT] Creating table PAYMENT...
INFO  [STDOUT] ...done!

Tip

If you’re having trouble creating the database, shut down JBoss. Then run the Ant build target clean.db. This will remove all database files and allow you to start fresh.

The persistence of all other entity beans used in this exercise is managed by the container (CMP), so JBoss will create the needed tables for them automatically.

Create a New JMS Topic

Because the TravelAgent EJB will publish messages in a JMS topic, you’ll have to create this new topic in JBoss. This exercise walks you through two different ways to create a new JMS topic: through an XML configuration file and through the JBoss JMX HTTP connector.

Adding a JMS Topic through a configuration file

The most common way to set up a JMS topic is to use an XML configuration file. As you learned in the installation chapter, every component in JBoss is a JMX MBean that can be hot-deployed. This part of the exercise shows you how to write a JMX MBean definition for a new JMS topic.

You can find the JMX configuration file in the ex12_1/src/resources/services directory.

jbossmq-titantopic-service.xml

<server>
  <mbean code="org.jboss.mq.server.jmx.Topic"
         name="jboss.mq.destination:service=Topic,
               name=titan-TicketTopic">
    <depends optional-attribute-name="DestinationManager"
     >jboss.mq:service=DestinationManager</depends>
  </mbean>
</server>

Each set of MBeans in a JMX configuration file must be defined within a <server> tag. An MBean itself is declared in an <mbean> tag. The only MBean declaration in this file defines the actual JMS topic you’ll use for the example code in this chapter. Each MBean is uniquely identified by its name, called an ObjectName. JMX ObjectNames can include any number of key-value parameters to describe the MBean further. In our case, the MBean class representing the JMS topic is declared first (org.jboss.mq.server.jmx.Topic), along with its JMX ObjectName (jboss.mq.destination:service=Topic, name=titan-TicketTopic). For JMS topic MBeans, a single parameter is useful: name. This is where the name of the JMS topic is defined (titan-TicketTopic).

One thing to note is that the application server must deploy the DestinationManager MBean before any queue or topic is deployed. This dependency is declared in jbossmq-titantopic-service.xml’s depends tag. JBoss will take care of satisfying this dependency and make sure the titan-TicketTopic isn’t started until the DestinationManager MBean has finished initializing and is ready to provide services to new queues and topics. Copying this file into the JBoss deploy directory will hot-deploy the JMS topic and make it ready for use.

We’ve defined a make-topic Ant target for deploying the topic bean. Run this target to copy jbossmq-titantopic-service.xml into JBoss’s deploy directory:

C:workbookex12_1>ant make-topic
Buildfile: build.xml

make-topic:
     [copy] Copying 1 file to C:jboss-4.0serverdefaultdeploy

On the server side, the following line is displayed:

[titan-TicketTopic] Bound to JNDI name: topic/titan-TicketTopic

Adding a JMS Topic through the JMX HTTP connector

An XML configuration file is the preferred means to deploy a JMS topic permanently, but for quick tests and such an alternative approach that uses JBoss’s JMX HTTP connector and the DestinationManager is sometimes better, because the topic lives in JBoss only until the application server is shut down. First open your browser and go to http://localhost:8080/jmx-console/, where you can browse through all deployed JBoss JMX MBeans. Scroll down to the jboss.mq section and find in it the MBean service DestinationManager (Figure 29-1).

Finding the DestinationManager

Figure 29-1. Finding the DestinationManager

Click on the service=DestinationManager link and you get a list of the MBean’s attributes and operations. One of the operations, createTopic( ), allows you to create a new JMS topic (Figure 29-2).

Naming a new JMS topic

Figure 29-2. Naming a new JMS topic

Type the name of the new JMS topic in the text area, and click on the Invoke button associated with the createTopic( ) operation. The Destination Manager will create the JMS topic and display a status message (Figure 29-3).

Confirming topic creation

Figure 29-3. Confirming topic creation

To see your new JMS topic MBean, go back to the home page of the JMX HTTP connector and search for the jboss.mq.destination domain. You should be able to see your new topic MBean (Figure 29-4).

Finding the new topic

Figure 29-4. Finding the new topic

Note that you can use the JMX HTTP connector to see the status of your topics and queues even if you create then in an XML configuration file.

Examine the EJB Standard Files

The ejb-jar.xml deployment descriptor is equivalent to the one for Exercise 11.2 except for the TravelAgent EJB. The definition for this bean has been extended to reference the JMS topics you just created.

ejb-jar.xml

<session>
  <ejb-name>TravelAgentEJB</ejb-name>
  <home>com.titan.travelagent.TravelAgentHomeRemote</home>
  <remote>com.titan.travelagent.TravelAgentRemote</remote>
  <ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
  <session-type>Stateful</session-type>
  <transaction-type>Container</transaction-type>
  ...
  <resource-ref>
    <res-ref-name>jdbc/titanDB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  <resource-ref>
    <res-ref-name>jms/TopicFactory</res-ref-name>
    <res-type>javax.jms.TopicConnectionFactory</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  <resource-env-ref>
    <resource-env-ref-name>jms/TicketTopic</resource-env-ref-name>
    <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
  </resource-env-ref>
</session>

A reference to a TopicConnectionFactory is declared in the same way as a reference to a DataSource. The definition contains the name of the resource (jms/TopicFactory), the class of the resource (javax.jms.TopicConnectionFactory), and whether the container or the bean performs the authentication.

Examine the JBoss-Specific Files

The TravelAgentEJB definition in jboss.xml must be modified as well, to describe the JMS topic references declared in ejb-jar.xml.

jboss.xml

...
<session>
  <ejb-name>TravelAgentEJB</ejb-name>
  <jndi-name>TravelAgentHomeRemote</jndi-name>
  <resource-ref>
    <res-ref-name>jdbc/titanDB</res-ref-name>
    <jndi-name>java:/DefaultDS</jndi-name>
  </resource-ref>
  <resource-ref>
    <res-ref-name>jms/TopicFactory</res-ref-name>
    <jndi-name>java:/JmsXA</jndi-name>
  </resource-ref>
  <resource-env-ref>
    <resource-env-ref-name>jms/TicketTopic</resource-env-ref-name>
    <jndi-name>topic/titan-TicketTopic</jndi-name>
  </resource-env-ref>
</session>
...

The <resource-ref> entry from ejb-jar.xml is mapped in the jboss.xml file to the JNDI name java:/JmsXA. If you take a look at the JBossMQ default configuration file in $JBOSS_HOME/server/default/deploy/jms/jms-ds.xml, you’ll see that the XA connection manager is bound to this name by default.

The last part of the TravelAgent EJB descriptor in jboss.xml maps the jms/TicketTopic name from the JNDI ENC of the bean to the topic/titan-TicketTopic JNDI name. This name corresponds to the JMS topic you just created.

Build and Deploy the Example Programs

Perform the following steps:

  1. Open a command prompt or shell terminal and change to the ex12_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:workbookex12_1> set JAVA_HOME=C:jdk1.4.2 C:workbookex12_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.

    Windows:C:workbookex12_1> set PATH=..antin;%PATH%
    Unix:$ export PATH=../ant/bin:$PATH
  4. Perform the build by typing ant.

You will see titan.jar rebuilt, copied to the JBoss deploy directory, and redeployed by the application server.

Examine the Client Applications

This exercise includes two client applications. You can find the code for them in the ex12_1/src/main/com/titan/clients directory.

The first application is the one used in Exercise 11.2 to make a reservation. The Ant target run.client_112b hasn’t changed, and needs no review.

The second application is new. JmsClient_1 subscribes to the titan-TicketTopic JMS topic and displays all messages published on it.

The application first gets an InitialContext, and looks up its TopicConnectionFactory and Topic.

JmsClient_1.java

...
Context jndiContext = getInitialContext( );

TopicConnectionFactory factory = (TopicConnectionFactory)
   jndiContext.lookup("ConnectionFactory");

Topic topic = (Topic) 
   jndiContext.lookup("topic/titan-TicketTopic");

The name of the JMS topic is the same as the one you created in Exercise 11.1, but the name of the TopicConnectionFactory is not the same as the one used by the TravelAgent EJB.

Remember that the java:/JmsXA connection factory used by the EJB was in the private JNDI space of the JBoss JVM (indicated by the java: prefix). Thus, the client application cannot look up this name from its JVM. For external applications, JBoss binds a set of connection factories within the public JNDI tree, each dedicated to a particular message transport protocol.

JBossMQ supports several different kinds of message invocation layers. Each layer has its own ConnectionFactory that is bound in JNDI, as shown in Table 29-1.

Table 29-1. JBossMQ message invocation layers

Invocation Layer

JNDI name

JVM

Hyperefficient invocation layer using standard Java method invocation, used for in-JVM JMS clients; external clients cannot use this invocation layer

java:/ConnectionFactory and

java:/XAConnectionFactory (with XA support)

RMI

RMI-based invocation layer

RMIConnectionFactory and

RMIXAConnectionFactory (with XA support)

OIL (Optimized Invocation Layer)

Uses custom TCP/IP sockets to obtain good network performance with a small memory footprint

ConnectionFactory and

XAConnectionFactory (with XA support)

UIL2

Used by client applications that cannot accept network connections originating from the server

UIL2ConnectionFactory and

UIL2XAConnectionFactory (with XA support)

We strongly suggest to use the UIL2 invocation layer; it is the most robust and efficient layer currently available.

TopicConnection connect = factory.createTopicConnection( );

TopicSession session = 
   connect.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 

TopicSubscriber subscriber = session.createSubscriber(topic);

subscriber.setMessageListener(this);

System.out.println
   ("Listening for messages on topic/titan-TicketTopic...");
connect.start( );

The end of the client application code is the same as in the EJB book.

Run the Client Applications

When you redeployed titan.jar, JBoss dropped and recreated the database tables, destroying any existing content. For this reason, you must have Ant execute the run.client_112a target to repopulate the database.

Tip

The run.client_112a target originated in Exercise 11.2, but we’ve duplicated it in the ex12_1 directory to facilitate your work.

Here’s the output:

C:workbookex12_1>ant run.client_112a
Buildfile: build.xml

prepare:

compile:

ejbjar:

run.client_112a:
  [java] Calling TravelAgentBean to create sample data..
  [java] All customers have been removed
  [java] All cabins have been removed
  [java] All ships have been removed
  [java] All cruises have been removed
  [java] All reservations have been removed
  [java] Customer with ID 1 created (Burke Bill)
  [java] Customer with ID 2 created (Labourey Sacha)
  [java] Created ship with ID 101...
  [java] Created ship with ID 102...
  [java] Created cabins on Ship A with IDs 100-109
  [java] Created cabins on Ship B with IDs 200-209
  [java] Created Alaska Cruise with ID 0 on ShipA
  [java] Created Norwegian Fjords Cruise with ID 1 on ShipA
  [java] Created Bermuda or Bust Cruise with ID 2 on ShipA
  [java] Created Indian Sea Cruise with ID 3 on ShipB
  [java] Created Australian Highlights Cruise with ID 4 on ShipB
  [java] Created Three-Hour Cruise with ID 5 on ShipB
  [java] Made reservation for Customer 1 on Cruise 0 for Cabin 103
  [java] Made reservation for Customer 1 on Cruise 5 for Cabin 208
  [java] Made reservation for Customer 2 on Cruise 1 for Cabin 105
  [java] Made reservation for Customer 2 on Cruise 5 for Cabin 202

BUILD SUCCESSFUL

For your new application to receive the message published on the JMS topic, you have to start it first:

C:workbookex12_1>ant run.client_121
Buildfile: build.xml

prepare:

compile:

ejbjar:

client_121:
     [java] Listening for messages on topic/titan-TicketTopic...

The last line of the output confirms that the client application has successfully subscribed to the topic and is waiting for messages.

Now you need to make some reservations exactly as you did in Exercise 11.2. Open a new shell and use the BookPassage script to make a reservation for Bill Burke on the Three-Hour Cruise for cabin 101 at $3,000.00:

C:workbookex12_1>BookPassage 1 5 101 3000.0
Buildfile: build.xml

prepare:

compile:

ejbjar:

run.client_112b:
     [java] Finding reference to Customer 1
     [java] Starting TravelAgent Session...
     [java] Setting Cruise and Cabin information in TravelAgent..
     [java] Booking the passage on the Cruise!
     [java] Ending TravelAgent Session...
     [java] Result of bookPassage:
     [java] Bill Burke has been booked for the Three-Hour Cruise cruise on ship 
Bohemian Rhapsody.
     [java]  Your accommodations include Suite 101 a 1 bed cabin on deck level 1.
     [java]  Total charge = 3000.0

In the JMS subscriber window you started, the following lines should appear:

[java] Listening for messages on topic/titan-TicketTopic...
[java]
[java]  RESERVATION RECEIVED:
[java] Bill Burke has been booked for the Three-Hour Cruise cruise on ship 
Bohemian Rhapsody.
[java]  Your accommodations include Suite 101 a 1 bed cabin on deck level 1.
[java]  Total charge = 3000.0

Remember from the EJB section of this book that our client application uses a nondurable subscription to the topic. Consequently, all the messages sent while the subscriber client application is not running are lost. That would not be the case if we had used a durable subscription to the topic.

To see the “many-to-many” nature of JMS topics, launch several JMS listener applications at the same time. They will all receive the messages sent to the topic.

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

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