Java Tutorial - Java Scipt : EJB Example

Java Tutorial - Java Scipt :

EJB Example

XML is just as easy to use within an EJB. We’ll modify the XSLT example to work as a message-driven bean. This is a useful model because you can queue up XSLT transformations that often take up a lot of processing time. In this example, our sample XSLT MDB will transform documents received in JMS messages. Our source document will once again be the order.xml, sent as a string within JMS text messages. Once transformed, the resultant HTML is saved to a directory for future access. There are several files we need to package in the EJB .jar file. In addition to the usual descriptors in META-INF, we also store resources used by the message-driven bean under the WEB-INF directory. The library .jar for dom4j, which we’ll be using for our XML work, is stored here. The other resource file is our XSLT stylesheet, order_to_html.xsl, which is used by the EJB to transform incoming messages. The contents of the order_to_html.xsl file are the same as in our XSLT example earlier in this chapter.
The layout for the directory is as follows:

\META-INF\ejb-jar.xml
\META-INF\jboss.xml
\WEB-INF\order_to_html.xsl
\WEB-INF\lib\dom4j-full.jar

Be sure that the directory and file layout match the above example. When we create the EJB .jar, that directory layout is expected. Any missing files will cause problems upon deployment in the EJB container.
Here’s the source for SampleXsltMessageBean.java:


import java.io.*;
import javax.ejb.*;
import javax.jms.*;
import javax.naming.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import org.dom4j.*;
import org.dom4j.io.*;
public class SampleXsltMessageBean
implements MessageDrivenBean, MessageListener {
public static final String OUTPUT_DIRECTORY = “/temp/”;
protected MessageDrivenContext m_context = null;
protected Topic m_topic = null;
protected TopicConnection m_connection = null;
protected TopicSession m_session = null;
public void setMessageDrivenContext( MessageDrivenContext context )
throws EJBException {
m_context = context;
}
/**
* Create the message-driven bean.
**/
public void ejbCreate() throws CreateException {
try {
// --- Allocate JMS resources ---
InitialContext context = new InitialContext();
TopicConnectionFactory factory = (TopicConnectionFactory)
context.lookup( “XAConnectionFactory” );
m_topic = (Topic)
context.lookup( “java:comp/env/jms/destinationTopic” );
m_connection = factory.createTopicConnection();
}
catch( Exception e ) {
throw new CreateException( e.getMessage() );
}
}
public void ejbRemove() {
// --- Release cached JMS resources. ---
if( m_topic != null ) {
m_topic = null;
}
if( m_connection != null ) {
try {
m_connection.close();
Adding XML Power Tools 473
}
catch( JMSException e ) {
e.printStackTrace();
}
m_connection = null;
}
}
public void onMessage( Message oMessage ) {
//= Retrieve from message ---
if( oMessage instanceof TextMessage ) {
TextMessage oTextMessage = (TextMessage) oMessage;
try {
//=== Read in the document from the JMS message. ---
SAXReader oReader = new SAXReader();
Document oDocument = oReader.read(
new StringReader( oTextMessage.getText() ) );
//=== Create the stylesheet and transformer. ---
InputStream oStylesheetInputStream =
getClass().getResourceAsStream( “WEB-INF/order_to_html.xsl” );
StreamSource oStylesheetSource =
new StreamSource( oStylesheetInputStream );
Transformer oTransformer =
TransformerFactory
.newInstance().newTransformer( oStylesheetSource );
//=== Transform the order XML document and output it as order.html.
DocumentSource oDocumentSource =
new DocumentSource( oDocument );
File oOutputFile = new File( OUTPUT_DIRECTORY + “order.html” );
StreamResult oResult = new StreamResult( oOutputFile );
System.out.println( “transformed and save to: “ + oOutputFile );
oTransformer.transform( oDocumentSource, oResult );
}
catch( Exception e ) {
e.printStackTrace();
}
}
}
}

To compile SampleXsltMessageBean.java on Windows, the command is:

javac -classpath .;%JBOSS_HOME%\client\jbossall-client.jar;WEBINF\lib\dom4j-full.jar SampleXsltMessageBean.java

On Linux, it is:

javac -classpath .:$JBOSS_HOME/client/jbossall-client.jar:WEBINF/lib/dom4j-full.jar SampleXsltMessageBean.java

After the SampleXsltMessageBean is compiled, we need to jar up the directory for deployment as an EJB .jar file. The command to create package SampleXsltMDB.jar is:

jar cvf SampleXsltMDB.jar SampleXsltMessageBean.class META-INF WEB-INF

The next step is to deploy the MDB. On JBoss, merely copy the Sample XsltMDB.jar to the deployment folder.  On Windows, this is: copy SampleXsltMDB.jar %JBOSS_HOME%\server\default\deploy

On Linux, it is:

cp SampleXsltMDB.jar $JBOSS_HOME/server/default/deploy

If the EJB container is running, the .jar file should be automatically deployed. Now in order to test it, we still need a client to send JMS messages to the MDB. The client to our message-driven bean is a simple Java application that publishes a text message to the topic that the MDB is hooked into. The program is based on the SimplePublisher.java from Chapter 9, except that we replace the contents of the message with the text of order.xml. The code is repeated here for your convenience. Here’s the source for the modified SimplePublisher.java:

import java.io.*;
import java.util.*;
import javax.jms.*;
import javax.naming.*;
/**
* Simple JMS Publisher
*/
public class SimplePublisher {
public static void main( String[] args ) {
TopicConnection connection = null;
TopicSession session = null;
try {
// --- Create default properties to find JBoss’s JNDI. ---
Hashtable default_properties = new Hashtable();
Adding XML Power Tools 475
default_properties.put(
Context.INITIAL_CONTEXT_FACTORY,
“org.jnp.interfaces.NamingContextFactory” );
default_properties.put( Context.PROVIDER_URL, “localhost:1099” );
// --- Create various JMS resources. ---
// -- Note that we are using the transaction aware versions of
// -- everything.
Context context = new InitialContext( default_properties );
TopicConnectionFactory factory = (TopicConnectionFactory)
context.lookup( “java:/XAConnectionFactory” );
connection = factory.createTopicConnection();
session = connection
.createTopicSession( true, Session.AUTO_ACKNOWLEDGE );
Topic topic = (Topic) context.lookup( “topic/testTopic” );
// -- We use topic/testTopic as the topic to publish to because it
// -- is defined by default by JBossMQ. You can find the queues
// -- and topics available at JBoss startup time within the
// -- jbossmq-destinations-service.xml file inside the
// -- %JBOSS_HOME%\server\default directory.
TopicPublisher publisher = session.createPublisher( topic );
// --- Publish an order.xml text message. ---
StringBuffer sb = new StringBuffer();
BufferedReader oReader =
new BufferedReader( new FileReader( “order.xml” ) );
while( oReader.ready() ) {
sb.append( oReader.readLine() );
}
TextMessage message = session.createTextMessage();
message.setText( sb.toString() );
publisher.publish( message );
session.commit();
System.out.println( “Published “ + message );
}
catch( Exception e ) {
e.printStackTrace();
}
finally {
try {
if( session != null ) {
session.close();
}
}

catch( JMSException e2 ) {
e2.printStackTrace();
}
try {
if( connection != null ) {
connection.close();
}
}
catch( JMSException e2 ) {
e2.printStackTrace();
}
}
}
}

Compilation is the same as before. On Windows, the command is:

javac -classpath .;%JBOSS_HOME%\client\jbossall-client.jarSimplePublisher.java

On Linux, it is:

javac -classpath .:$JBOSS_HOME/client/jbossall-client.jar SimplePublisher.java

To run the client on Windows, use the following command:

java -classpath .;%JBOSS_HOME%\client\jbossallclient. jar;%JBOSS_HOME%\client\log4j.jar SimplePublisher

On Linux, use:

java -classpath .:$JBOSS_HOME/client/jbossallclient.
jar:$JBOSS_HOME/client/log4j.jar SimplePublisher

Assuming that the MDB is deployed, you can run the client program to trigger the transformation. With the default settings, the order.html file will be created under c:\temp\order.html. To recap, we constructed a MDB that uses dom4j to transform documents received via JMS messages. Queued transformations are quite useful in many scenarios. Our example does a trivial transformation, but the documents, stylesheets, and output can all be easily changed to fit your own needs. Best of all, you can see that these pieces can work together in various combinations to get the behavior and meet the constraints that are required to solve the problems you face.