A J2EE Application That Uses the JMS API with a Session Bean

This section explains how to write, compile, package, deploy, and run a J2EE application that uses the JMS API in conjunction with a session bean. The application contains the following components:

The section covers the following topics:

You will find the source files for this section in the directory <INSTALL>/j2eetutorial14/examples/jms/clientsessionmdb/. Path names in this section are relative to this directory.

Writing the Application Components

This application demonstrates how to send messages from an enterprise bean--in this case, a session bean--rather than from an application client, as in the example in Chapter 28. Figure 34-1 illustrates the structure of this application.

A J2EE Application: Client to Session Bean to Message-Driven Bean

Figure 34-1 A J2EE Application: Client to Session Bean to Message-Driven Bean

The Publisher enterprise bean in this example is the enterprise-application equivalent of a wire-service news feed that categorizes news events into six news categories. The message-driven bean could represent a newsroom, where the sports desk, for example, would set up a subscription for all news events pertaining to sports.

The application client in the example obtains a handle to the Publisher enterprise bean's remote home interface, creates an instance of the bean, and then calls the bean's business method. The enterprise bean creates 18 text messages. For each message, it sets a String property randomly to one of six values representing the news categories and then publishes the message to a topic. The message-driven bean uses a message selector for the property to limit which of the published messages it receives.

Writing the components of the application involves the following:

Coding the Application Client: MyAppClient.java

The application client program, src/MyAppClient.java, performs no JMS API operations and so is simpler than the client program in Chapter 28. The program obtains a handle to the Publisher enterprise bean's remote home interface, using the JNDI naming context java:comp/env. The program then creates an instance of the bean and calls the bean's business method twice.

Coding the Publisher Session Bean

The Publisher bean is a stateless session bean that has one create method and one business method. The Publisher bean uses remote interfaces rather than local interfaces because it is accessed from the application client.

The remote home interface source file is src/PublisherHome.java.

The remote interface, src/PublisherRemote.java, declares a single business method, publishNews.

The bean class, src/PublisherBean.java, implements the publishNews method and its helper method chooseType. The bean class also implements the required methods ejbCreate, setSessionContext, ejbRemove, ejbActivate, and ejbPassivate.

The ejbCreate method of the bean class allocates resources--in this case, by looking up the ConnectionFactory and the topic and creating the Connection. The business method publishNews creates a Session and a MessageProducer and publishes the messages.

The ejbRemove method must deallocate the resources that were allocated by the ejbCreate method. In this case, the ejbRemove method closes the Connection.

Coding the Message-Driven Bean: MessageBean.java

The message-driven bean class, src/MessageBean.java, is identical to the one in Chapter 28. However, the deployment descriptor will be different, because instead of a queue the bean is using a topic with a durable subscription.

Creating and Packaging the Application

This example uses the topic named jms/Topic and the connection factory jms/ConnectionFactory, which you created in Creating JMS Administered Objects. It also uses the connection factory jms/DurableConnectionFactory, which you created in A Message Acknowledgment Example and A Durable Subscription Example. If you deleted any of these objects, create them again.

Creating and packaging this application involve six steps:

Compiling the Source Files and Starting the Application Server

  1. In the directory <INSTALL>/j2eetutorial14/examples/jms/clientsessionmdb, use the build target to compile the source files:
  2. asant build

  3. Start the Application Server, if it is not already running.

Starting deploytool and Creating the Application

  1. Start deploytool. For instructions, see Starting the deploytool Utility.
  2. Choose FileRight ArrowNewRight ArrowApplication.
  3. Click Browse next to the Application File Name field, and use the file chooser to locate the directory clientsessionmdb.
  4. In the File Name field, type ClientSessionMDBApp.
  5. Click New Application.
  6. Click OK.

Packaging the Session Bean

To package the session bean, perform the following steps:

  1. Choose FileRight ArrowNewRight ArrowEnterprise Bean to start the Enterprise Bean wizard. Then click Next.
  2. In the EJB JAR General Settings screen:
    1. Select Create New JAR Module in Application and verify that the application is ClientSessionMDBApp.
    2. In the JAR Display Name field, type EBJAR.
    3. Click the Edit Contents button.
    4. In the dialog box, locate the build/sb/ directory. Select PublisherBean.class, PublisherHome.class, and PublisherRemote.class from the Available Files tree. Click Add and then OK.
  3. In the Bean General Settings screen:
    1. From the Enterprise Bean Class menu, choose sb.PublisherBean.
    2. Verify that the enterprise bean name is PublisherBean and that the enterprise bean type is Stateless Session.
    3. In the Remote Interfaces area, choose sb.PublisherHome from the Remote Home Interface menu, and choose sb.PublisherRemote from the Remote Interface menu.

After you finish the wizard, perform the following steps:

  1. Click the PublisherBean node, and then click the Msg Dest Ref's tab. In the inspector pane:
    1. Click Add. A dialog box opens.
    2. Type jms/TopicName in the Coded Name field.
    3. Choose javax.jms.Topic from the Destination Type combo box.
    4. Choose Produces from the Usage drop-down list.
    5. Type PhysicalTopic in the Destination Name combo box.
  2. Click the PublisherBean node, and then click the Resource Ref's tab. In the inspector pane:
    1. Click Add.
    2. Type jms/MyConnectionFactory in the Coded Name field.
    3. Choose javax.jms.ConnectionFactory from the Type drop-down list.
    4. Type jms/ConnectionFactory in the JNDI name combo box, and type guest in both the User Name and the Password fields.
  3. Click the PublisherBean node, and then click the Transactions tab. In the inspector pane, select the Container-Managed radio button.
  4. Click the EBJAR node, and then click the Message Destinations tab. In the inspector pane:
    1. Click Add.
    2. Type PhysicalTopic in the Destination Name field. When you press Enter, this name appears in the Display Name field, and PublisherBean appears in the Producers area.
    3. Type jms/Topic in the JNDI Name combo box.

Packaging the Message-Driven Bean

For greater efficiency, you will package the message-driven bean in the same JAR file as the session bean.

To package the message-driven bean, perform the following steps:

  1. Choose FileRight ArrowNewRight ArrowEnterprise Bean to start the Enterprise Bean wizard.
  2. In the EJB JAR General Settings screen:
    1. Select the Add to Existing JAR Module radio button, and verify that the module is EBJAR (ClientSessionMDBApp).
    2. Click the Edit Contents button.
    3. In the dialog box, locate the build/mdb/ directory. Select MessageBean.class from the Available Files tree. Click Add and then OK.
  3. In the Bean General Settings screen:
    1. From the Enterprise Bean Class menu, choose mdb.MessageBean.
    2. In the Enterprise Bean Name field, accept the default value, MessageBean.
    3. Verify that the enterprise bean type is Message-Driven.
  4. In the Message-driven Bean Settings screen:
    1. For the Messaging Service, accept the default, JMS.
    2. Choose javax.jms.Topic from the Destination Type combo box.
    3. Choose PhysicalTopic from the Target Message Destination combo box.
    4. Select the Durable Subscription checkbox. In the Subscription Name field, type MySub.
    5. In the Message Selector field, type the following:
    6.   NewsType = 'Sports' OR NewsType = 'Opinion'

      (If you cannot see the Message Selector field in the screen, expand the screen vertically.)

    7. In the Connection Factory JNDI Name (Sun-specific) field, type the following:
    8.   jms/DurableConnectionFactory

After you finish the wizard, perform the following steps:

  1. Click the MessageBean node, and then click the Transactions tab. In the inspector pane, select the Container-Managed radio button.
  2. Click the EBJAR node, and then click the Message Destinations tab and select PhysicalTopic. You will see that MessageBean now appears in the Consumers area.

Packaging the Application Client

To package the application client, perform the following steps:

  1. Choose FileRight ArrowNewRight ArrowApplication Client to start the Application Client wizard. Then click Next.
  2. In the JAR File Contents screen:
    1. Verify that Create New AppClient Module in Application is selected and that the application is ClientSessionMDBApp.
    2. In the AppClient Display Name field, type MyAppClient.
    3. Click the Edit Contents button.
    4. In the dialog box, locate the build/client/ directory. Select MyAppClient.class from the Available Files tree. Click Add and then OK.
  3. In the General screen, select client.MyAppClient from the Main Class drop-down list.

After you finish the wizard, click the EJB Ref's tab, and then click Add in the inspector pane. In the dialog box, do the following:

  1. Type ejb/remote/Publisher in the Coded Name field.
  2. Choose Session from the EJB Type drop-down list.
  3. Choose Remote from the Interfaces drop-down list.
  4. Choose sb.PublisherHome from the Home Interface combo box.
  5. Choose sb.PublisherRemote from the Local/Remote Interface combo box.
  6. In the Target EJB area, select JNDI Name and choose PublisherBean from the combo box.

Updating the JNDI Names

You need to update the JNDI name for the message-driven bean so that it specifies the destination it receives messages from.

  1. Select ClientSessionMDBApp and click Sun-specific Settings on the General screen.
  2. Type jms/Topic in the JNDI Name field for the MessageBean component.

Verify that the JNDI names for the application components are correct. They should appear as shown in Tables 34-1 and 34-2.

Table 34-1 Application Pane for ClientSessionMDBApp
Component Type
Component
JNDI Name
EJB
MessageBean
jms/Topic
EJB
PublisherBean
PublisherBean

Table 34-2 References Pane for ClientSessionMDBApp
Ref. Type
Referenced By
Reference Name
JNDI Name
EJB Ref
MyAppClient
ejb/remote/Publisher
PublisherBean
Resource
PublisherBean
jms/MyConnectionFactory
jms/ConnectionFactory

Deploying the Application

  1. Choose FileRight ArrowSave to save the application.
  2. Choose ToolsRight ArrowDeploy.
  3. In the dialog box, type your administrative user name and password (if they are not already filled in).
  4. In the Application Client Stub Directory area, select the Return Client Jar checkbox. If you wish to run the client in a directory other than the default, click Browse and use the file chooser to specify it.
  5. Click OK.
  6. In the Distribute Module dialog box, click Close when the process completes. You will find a file named ClientSessionMDBAppClient.jar in the specified directory.

Running the Application Client

To run the client, use the following command:

appclient -client ClientSessionMDBAppClient.jar 

The program output in the terminal window looks like this:

Looking up EJB reference
Looked up home
Narrowed home
Got the EJB
To view the bean output,
 check <install_dir>/domains/domain1/logs/server.log. 

The output from the enterprise beans appears in the server log (<J2EE_HOME>/domains/domain1/logs/server.log), wrapped in logging information. The Publisher session bean sends two sets of 18 messages numbered 0 through 17. Because of the message selector, the message-driven bean receives only the messages whose NewsType property is Sports or Opinion.

Suppose that the last few messages from the Publisher session bean look like this:

PUBLISHER: Setting message text to: Item 12: Business
PUBLISHER: Setting message text to: Item 13: Opinion
PUBLISHER: Setting message text to: Item 14: Living/Arts
PUBLISHER: Setting message text to: Item 15: Sports
PUBLISHER: Setting message text to: Item 16: Living/Arts
PUBLISHER: Setting message text to: Item 17: Living/Arts 

Because of the message selector, the last messages received by the message-driven bean will be the following:

MESSAGE BEAN: Message received: Item 13: Opinion
MESSAGE BEAN: Message received: Item 15: Sports 

If you like, you can rewrite the message selector to receive different messages.

Undeploy the application after you finish running the client.