Java/J2EE/Java Message Service JMS
Содержание
- 1 A durable subscription is active even when the subscriber is not active
- 2 A message will not be acknowledged until processing of it is complete
- 3 A simple implementation of a request/reply message exchange
- 4 Creates and reads messages in all supported JMS message formats: BytesMessage, TextMessage, MapMessage, StreamMessage, and ObjectMessage
- 5 Creates and then reads a StreamMessage and a BytesMessage
- 6 Creates a Producer and a Consumer objects (Producer and Consumer classes are defined in this file)
- 7 Demonstrates a simple end-to-end "Hello World" JMS example that can be compiled and run with the Sun Java(tm) System Message Queue product
- 8 Demonstrates that mutable objects are copied, not passed by reference, when you use them to create message objects
- 9 Demonstrates the use of transactions in a JMS application
- 10 Fetches one or more messages from a queue using asynchronous message delivery
- 11 Fetches one or more messages from a queue using synchronous message delivery
- 12 How to write a GUI application that uses a JMS QueueBrowser to browse the contents of a queue
- 13 MQ Cluster Monitor
- 14 Reads a textfile, creates a BytesMessage from it, then reads the message
- 15 Sends several messages to a queue
- 16 The BrokerMetrics example is a JMS application that monitors the Sun Java(tm) System Message Queue broker
- 17 The DestListMetrics example is a JMS application that monitors the destinations on a Sun Java(tm) System Message Queue broker
- 18 The DestMetrics example is a JMS application that monitors a destination on a Sun Java(tm) System Message Queue broker
- 19 The mqping utility is similar to the Unix ping utility in some regards
- 20 The simplest form of the publish/subscribe model: the producer publishes a message, and the consumer reads it using a synchronous receive
- 21 The TopicSelectors class demonstrates the use of multiple subscribers and message selectors
- 22 The UniversalClient example is a basic "client" application that uses the JMS 1.1 APIs
- 23 The use of a message listener in the publish/subscribe model. The producer publishes several messages, and the consumer reads them asynchronously
- 24 The use of message header fields
- 25 The VMMetrics example is a JMS application that monitors the Java VM used by the Sun Java(tm) System Message Queue broker
- 26 This example illustrates how JMS can be used to create a simple chat application
- 27 This example illustrates how JMS (Java Message Service) API can be used in a Java applet
- 28 This example is a simple JMS client application
A durable subscription is active even when the subscriber is not active
/*
* @(#)DurableSubscriberExample.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The DurableSubscriberExample class demonstrates that a durable subscription
* is active even when the subscriber is not active.
* <p>
* The program contains a DurableSubscriber class, a MultiplePublisher class,
* a main method, and a method that instantiates the classes and calls their
* methods in sequence.
* <p>
* The program begins like any publish/subscribe program: the subscriber starts,
* the publisher publishes some messages, and the subscriber receives them.
* <p>
* At this point the subscriber closes itself. The publisher then publishes
* some messages while the subscriber is not active. The subscriber then
* restarts and receives the messages.
* <p>
* Specify a topic name on the command line when you run the program.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class DurableSubscriberExample {
String topicName = null;
int exitResult = 0;
static int startindex = 0;
/**
* The DurableSubscriber class contains a constructor, a startSubscriber
* method, a closeSubscriber method, and a finish method.
* <p>
* The class fetches messages asynchronously, using a message listener,
* TextListener.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class DurableSubscriber {
Connection connection = null;
Session session = null;
Topic topic = null;
TopicSubscriber topicSubscriber = null;
TextListener topicListener = null;
/**
* The TextListener class implements the MessageListener interface by
* defining an onMessage method for the DurableSubscriber class.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
private class TextListener implements MessageListener {
final SampleUtilities.DoneLatch monitor =
new SampleUtilities.DoneLatch();
/**
* Casts the message to a TextMessage and displays its text.
* A non-text message is interpreted as the end of the message
* stream, and the message listener sets its monitor state to all
* done processing messages.
*
* @param message the incoming message
*/
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage msg = (TextMessage) message;
try {
System.out.println("SUBSCRIBER: Reading message: "
+ msg.getText());
} catch (JMSException e) {
System.out.println("Exception in onMessage(): "
+ e.toString());
}
} else {
monitor.allDone();
}
}
}
/**
* Constructor: looks up a connection factory and topic and creates a
* connection and session.
*/
public DurableSubscriber() {
ConnectionFactory connectionFactory = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
connection.setClientID("DurableSubscriberExample");
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
}
/**
* Stops connection, then creates durable subscriber, registers message
* listener (TextListener), and starts message delivery; listener
* displays the messages obtained.
*/
public void startSubscriber() {
try {
System.out.println("Starting subscriber");
connection.stop();
topicSubscriber = session.createDurableSubscriber(topic,
"MakeItLast");
topicListener = new TextListener();
topicSubscriber.setMessageListener(topicListener);
connection.start();
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
}
}
/**
* Blocks until publisher issues a control message indicating
* end of publish stream, then closes subscriber.
*/
public void closeSubscriber() {
try {
topicListener.monitor.waitTillDone();
System.out.println("Closing subscriber");
topicSubscriber.close();
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
}
}
/**
* Closes the connection.
*/
public void finish() {
if (connection != null) {
try {
session.unsubscribe("MakeItLast");
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
/**
* The MultiplePublisher class publishes several messages to a topic. It
* contains a constructor, a publishMessages method, and a finish method.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class MultiplePublisher {
Connection connection = null;
Session session = null;
Topic topic = null;
MessageProducer topicPublisher = null;
/**
* Constructor: looks up a connection factory and topic and creates a
* connection and session. Also creates the producer.
*/
public MultiplePublisher() {
ConnectionFactory connectionFactory = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
topicPublisher = session.createProducer(topic);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
}
/**
* Creates text message.
* Sends some messages, varying text slightly.
* Messages must be persistent.
*/
public void publishMessages() {
TextMessage message = null;
int i;
final int NUMMSGS = 3;
final String MSG_TEXT = new String("Here is a message");
try {
message = session.createTextMessage();
for (i = startindex; i < startindex + NUMMSGS; i++) {
message.setText(MSG_TEXT + " " + (i + 1));
System.out.println("PUBLISHER: Publishing message: "
+ message.getText());
topicPublisher.send(message);
}
// Send a non-text control message indicating end of messages.
topicPublisher.send(session.createMessage());
startindex = i;
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
}
}
/**
* Closes the connection.
*/
public void finish() {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
/**
* Instantiates the subscriber and publisher classes.
*
* Starts the subscriber; the publisher publishes some messages.
*
* Closes the subscriber; while it is closed, the publisher publishes
* some more messages.
*
* Restarts the subscriber and fetches the messages.
*
* Finally, closes the connections.
*/
public void run_program() {
DurableSubscriber durableSubscriber = new DurableSubscriber();
MultiplePublisher multiplePublisher = new MultiplePublisher();
durableSubscriber.startSubscriber();
multiplePublisher.publishMessages();
durableSubscriber.closeSubscriber();
multiplePublisher.publishMessages();
durableSubscriber.startSubscriber();
durableSubscriber.closeSubscriber();
multiplePublisher.finish();
durableSubscriber.finish();
}
/**
* Reads the topic name from the command line, then calls the
* run_program method.
*
* @param args the topic used by the example
*/
public static void main(String[] args) {
DurableSubscriberExample dse = new DurableSubscriberExample();
if (args.length != 1) {
System.out.println("Usage: java DurableSubscriberExample <topic_name>");
System.exit(1);
}
dse.topicName = new String(args[0]);
System.out.println("Topic name is " + dse.topicName);
dse.run_program();
SampleUtilities.exit(dse.exitResult);
}
}
A message will not be acknowledged until processing of it is complete
/*
* @(#)AckEquivExample.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The AckEquivExample class shows how the following two scenarios both ensure
* that a message will not be acknowledged until processing of it is complete:
* <ul>
* <li> Using an asynchronous consumer (message listener) in an
* AUTO_ACKNOWLEDGE session
* <li> Using a synchronous consumer in a CLIENT_ACKNOWLEDGE session
* </ul>
* <p>
* With a message listener, the automatic acknowledgment happens when the
* onMessage method returns -- that is, after message processing has finished.
* <p>
* With a synchronous receive, the client acknowledges the message after
* processing is complete. (If you use AUTO_ACKNOWLEDGE with a synchronous
* receive, the acknowledgement happens immediately after the receive call; if
* any subsequent processing steps fail, the message cannot be redelivered.)
* <p>
* The program contains a SynchProducer class, a SynchConsumer class, an
* AsynchSubscriber class with a TextListener class, a MultiplePublisher class,
* a main method, and a method that runs the other classes" threads.
* <p>
* Specify a queue name and a topic name on the command line when you run the
* program. The program also uses a queue named "controlQueue", which should be
* created before you run the program.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class AckEquivExample {
final String CONTROL_QUEUE = "controlQueue";
String queueName = null;
String topicName = null;
int exitResult = 0;
/**
* The SynchProducer class creates a session in CLIENT_ACKNOWLEDGE mode and
* sends a message.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class SynchProducer extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageProducer msgProducer = null;
final String MSG_TEXT =
new String("Here is a client-acknowledge message");
TextMessage message = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.CLIENT_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create client-acknowledge producer.
* Create and send message.
*/
try {
System.out.println("PRODUCER: Created client-acknowledge session");
msgProducer = session.createProducer(queue);
message = session.createTextMessage();
message.setText(MSG_TEXT);
System.out.println("PRODUCER: Sending message: "
+ message.getText());
msgProducer.send(message);
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The SynchConsumer class creates a session in CLIENT_ACKNOWLEDGE mode and
* receives the message sent by the SynchProducer class.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class SynchConsumer extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageConsumer msgConsumer = null;
TextMessage message = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.CLIENT_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create client-acknowledge consumer.
* Receive message and process it.
* Acknowledge message.
*/
try {
System.out.println("CONSUMER: Created client-acknowledge session");
msgConsumer = session.createConsumer(queue);
connection.start();
message = (TextMessage) msgConsumer.receive();
System.out.println("CONSUMER: Processing message: "
+ message.getText());
System.out.println("CONSUMER: Now I"ll acknowledge the message");
message.acknowledge();
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The AsynchSubscriber class creates a session in AUTO_ACKNOWLEDGE mode
* and fetches several messages from a topic asynchronously, using a
* message listener, TextListener.
* <p>
* Each message is acknowledged after the onMessage method completes.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class AsynchSubscriber extends Thread {
/**
* The TextListener class implements the MessageListener interface by
* defining an onMessage method for the AsynchSubscriber class.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
private class TextListener implements MessageListener {
final SampleUtilities.DoneLatch monitor =
new SampleUtilities.DoneLatch();
/**
* Casts the message to a TextMessage and displays its text.
* A non-text message is interpreted as the end of the message
* stream, and the message listener sets its monitor state to all
* done processing messages.
*
* @param message the incoming message
*/
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage msg = (TextMessage) message;
try {
System.out.println("CONSUMER: Processing message: "
+ msg.getText());
} catch (JMSException e) {
System.out.println("Exception in onMessage(): "
+ e.toString());
}
} else {
monitor.allDone();
}
}
}
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
TopicSubscriber topicSubscriber = null;
TextListener topicListener = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
connection.setClientID("AckEquivExample");
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
System.out.println("CONSUMER: Created auto-acknowledge session");
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create auto-acknowledge subscriber.
* Register message listener (TextListener).
* Start message delivery.
* Send synchronize message to publisher, then wait till all
* messages have arrived.
* Listener displays the messages obtained.
*/
try {
topicSubscriber = session.createDurableSubscriber(topic,
"AckEquivExampleSubscription");
topicListener = new TextListener();
topicSubscriber.setMessageListener(topicListener);
connection.start();
// Let publisher know that subscriber is ready.
try {
SampleUtilities.sendSynchronizeMessage("CONSUMER: ",
CONTROL_QUEUE);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Asynchronously process messages.
* Block until publisher issues a control message indicating
* end of publish stream.
*/
topicListener.monitor.waitTillDone();
topicSubscriber.close();
session.unsubscribe("AckEquivExampleSubscription");
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The MultiplePublisher class creates a session in AUTO_ACKNOWLEDGE mode
* and publishes three messages to a topic.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class MultiplePublisher extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
MessageProducer topicPublisher = null;
TextMessage message = null;
final int NUMMSGS = 3;
final String MSG_TEXT =
new String("Here is an auto-acknowledge message");
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
System.out.println("PRODUCER: Created auto-acknowledge session");
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* After synchronizing with subscriber, create publisher.
* Send 3 messages, varying text slightly.
* Send end-of-messages message.
*/
try {
/*
* Synchronize with subscriber. Wait for message indicating
* that subscriber is ready to receive messages.
*/
try {
SampleUtilities.receiveSynchronizeMessages("PRODUCER: ",
CONTROL_QUEUE, 1);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
topicPublisher = session.createProducer(topic);
message = session.createTextMessage();
for (int i = 0; i < NUMMSGS; i++) {
message.setText(MSG_TEXT + " " + (i + 1));
System.out.println("PRODUCER: Publishing message: "
+ message.getText());
topicPublisher.send(message);
}
// Send a non-text control message indicating end of messages.
topicPublisher.send(session.createMessage());
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* Instantiates the producer, consumer, subscriber, and publisher classes and
* starts their threads.
* Calls the join method to wait for the threads to die.
*/
public void run_threads() {
SynchProducer synchProducer = new SynchProducer();
SynchConsumer synchConsumer = new SynchConsumer();
AsynchSubscriber asynchSubscriber = new AsynchSubscriber();
MultiplePublisher multiplePublisher = new MultiplePublisher();
synchProducer.start();
synchConsumer.start();
try {
synchProducer.join();
synchConsumer.join();
} catch (InterruptedException e) {}
asynchSubscriber.start();
multiplePublisher.start();
try {
asynchSubscriber.join();
multiplePublisher.join();
} catch (InterruptedException e) {}
}
/**
* Reads the queue and topic names from the command line, then calls the
* run_threads method to execute the program threads.
*
* @param args the topic used by the example
*/
public static void main(String[] args) {
AckEquivExample aee = new AckEquivExample();
if (args.length != 2) {
System.out.println("Usage: java AckEquivExample <queue_name> <topic_name>");
System.exit(1);
}
aee.queueName = new String(args[0]);
aee.topicName = new String(args[1]);
System.out.println("Queue name is " + aee.queueName);
System.out.println("Topic name is " + aee.topicName);
aee.run_threads();
SampleUtilities.exit(aee.exitResult);
}
}
A simple implementation of a request/reply message exchange
/*
* @(#)RequestReplyQueue.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The RequestReplyQueue class illustrates a simple implementation of a
* request/reply message exchange. It uses the QueueRequestor class provided
* by JMS. Providers and clients can create more sophisticated versions of
* this facility.
* <p>
* The program contains a Request class, a Reply class, a main method, and
* a method that runs the sender and receiver threads.
*
* @author Kim Haase
* @version 1.5, 08/14/00
*/
public class RequestReplyQueue {
String queueName = null;
int exitResult = 0;
/**
* The Request class represents the request half of the message exchange.
*
* @author Kim Haase
* @version 1.5, 08/14/00
*/
public class Request extends Thread {
/**
* Runs the thread.
*/
public void run() {
QueueConnectionFactory queueConnectionFactory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
Queue queue = null;
QueueRequestor queueRequestor = null;
TextMessage message = null;
final String MSG_TEXT = new String("Here is a request");
TextMessage reply = null;
String replyID = null;
try {
queueConnectionFactory =
SampleUtilities.getQueueConnectionFactory();
queueConnection =
queueConnectionFactory.createQueueConnection();
queueSession = queueConnection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, (Session) queueSession);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (queueConnection != null) {
try {
queueConnection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create a QueueRequestor.
* Create a text message and set its text.
* Start delivery of incoming messages.
* Send the text message as the argument to the request method,
* which returns the reply message. The request method also
* creates a temporary queue and places it in the JMSReplyTo
* message header field.
* Extract and display the reply message.
* Read the JMSCorrelationID of the reply message and confirm that
* it matches the JMSMessageID of the message that was sent.
* Finally, close the connection.
*/
try {
queueRequestor = new QueueRequestor(queueSession, queue);
message = queueSession.createTextMessage();
message.setText(MSG_TEXT);
System.out.println("REQUEST: Sending message: "
+ message.getText());
queueConnection.start();
reply = (TextMessage) queueRequestor.request(message);
System.out.println("REQUEST: Reply received: "
+ reply.getText());
replyID = new String(reply.getJMSCorrelationID());
if (replyID.equals(message.getJMSMessageID())) {
System.out.println("REQUEST: OK: Reply matches sent message");
} else {
System.out.println("REQUEST: ERROR: Reply does not match sent message");
}
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} catch (Exception ee) {
System.out.println("Unexpected exception: " + ee.toString());
ee.printStackTrace();
exitResult = 1;
} finally {
if (queueConnection != null) {
try {
queueConnection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The Reply class represents the reply half of the message exchange.
*
* @author Kim Haase
* @version 1.5, 08/14/00
*/
public class Reply extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageConsumer msgConsumer = null;
TextMessage message = null;
Queue tempQueue = null;
MessageProducer replyProducer = null;
TextMessage reply = null;
final String REPLY_TEXT = new String("Here is a reply");
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create a MessageConsumer.
* Start delivery of incoming messages.
* Call receive, which blocks until it obtains a message.
* Display the message obtained.
* Extract the temporary reply queue from the JMSReplyTo field of
* the message header.
* Use the temporary queue to create a sender for the reply message.
* Create the reply message, setting the JMSCorrelationID to the
* value of the incoming message"s JMSMessageID.
* Send the reply message.
* Finally, close the connection.
*/
try {
msgConsumer = session.createConsumer(queue);
connection.start();
message = (TextMessage) msgConsumer.receive();
System.out.println("REPLY: Message received: "
+ message.getText());
tempQueue = (Queue) message.getJMSReplyTo();
replyProducer = session.createProducer(tempQueue);
reply = session.createTextMessage();
reply.setText(REPLY_TEXT);
reply.setJMSCorrelationID(message.getJMSMessageID());
System.out.println("REPLY: Sending reply: " + reply.getText());
replyProducer.send(reply);
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} catch (Exception ee) {
System.out.println("Unexpected exception: " + ee.toString());
ee.printStackTrace();
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* Instantiates the Request and Reply classes and starts their
* threads.
* Calls the join method to wait for the threads to die.
*/
public void run_threads() {
Request request = new Request();
Reply reply = new Reply();
request.start();
reply.start();
try {
request.join();
reply.join();
} catch (InterruptedException e) {}
}
/**
* Reads the queue name from the command line, then calls the
* run_threads method to execute the program threads.
*
* @param args the queue used by the example
*/
public static void main(String[] args) {
RequestReplyQueue rrq = new RequestReplyQueue();
if (args.length != 1) {
System.out.println("Usage: java RequestReplyQueue <queue_name>");
System.exit(1);
}
rrq.queueName = new String(args[0]);
System.out.println("Queue name is " + rrq.queueName);
rrq.run_threads();
SampleUtilities.exit(rrq.exitResult);
}
}
Creates and reads messages in all supported JMS message formats: BytesMessage, TextMessage, MapMessage, StreamMessage, and ObjectMessage
/*
* @(#)MessageFormats.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The MessageFormats class consists only of a main method, which creates and
* then reads messages in all supported JMS message formats: BytesMessage,
* TextMessage, MapMessage, StreamMessage, and ObjectMessage. It does not send
* the messages.
* <p>
* Before it can read a BytesMessage or StreamMessage that has not been sent,
* the program must call reset() to put the message body in read-only mode
* and reposition the stream.
*
* @author Kim Haase
* @version 1.4, 08/09/00
*/
public class MessageFormats {
/**
* Main method. Takes no arguments.
*/
public static void main(String[] args) {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
BytesMessage bytesMessage = null;
byte[] byteData = {-128, 127, -1, 0, 1, -64, 64};
int length = 0;
byte[] inByteData = new byte[7];
TextMessage textMessage = null;
String msgText = "This is a text message.";
MapMessage mapMessage = null;
StreamMessage streamMessage = null;
ObjectMessage objectMessage = null;
String object = "A String is an object.";
int exitResult = 0;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
try {
/*
* Create a BytesMessage, then write it from an array of
* bytes (signed 8-bit integers).
* Reset the message for reading, then read the bytes into a
* second array.
* A BytesMessage is an undifferentiated stream of bytes that can
* be read in various formats.
*/
bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(byteData);
bytesMessage.reset();
length = bytesMessage.readBytes(inByteData);
System.out.println("Reading BytesMessage " + length
+ " bytes long:");
for (int i = 0; i < length; i++) {
System.out.print(" " + inByteData[i]);
}
System.out.println();
/*
* Create, write, and display the contents of a TextMessage.
* A TextMessage contains a String of any length.
*/
textMessage = session.createTextMessage();
textMessage.setText(msgText);
System.out.println("Reading TextMessage:");
System.out.println(" " + textMessage.getText());
/*
* Create and write a MapMessage, then display its contents in
* a different order.
* A MapMessage contains a series of name/value pairs.
* The name is a string; the value can be of various types.
* The receiving program can read any or all of the values,
* in any order.
*/
mapMessage = session.createMapMessage();
mapMessage.setString("Message type", "Map");
mapMessage.setInt("An Integer", 3456);
mapMessage.setDouble("A Double", 1.23456789);
System.out.println("Reading MapMessage in a different order"
+ " from the way it was generated:");
System.out.println(" Type: "
+ mapMessage.getString("Message type"));
System.out.println(" Double: "
+ mapMessage.getDouble("A Double"));
System.out.println(" Integer: "
+ mapMessage.getInt("An Integer"));
/*
* Create and write a StreamMessage.
* Reset the message for reading and display the values.
* A StreamMessage can also contain values of various types.
* They must be read in the same order in which they were
* written.
*/
streamMessage = session.createStreamMessage();
streamMessage.writeString("Stream message");
streamMessage.writeDouble(123.456789e222);
streamMessage.writeInt(223344);
streamMessage.reset();
System.out.println("Reading StreamMessage in the order"
+ " in which it was generated:");
System.out.println(" String: "
+ streamMessage.readString());
System.out.println(" Double: "
+ streamMessage.readDouble());
System.out.println(" Integer: "
+ streamMessage.readInt());
/*
* Create an ObjectMessage from a String object, then
* display its contents.
* An ObjectMessage can contain any Java object. This example
* uses a String for the sake of simplicity. The program that
* reads the object casts it to the appropriate type.
*/
objectMessage = session.createObjectMessage();
objectMessage.setObject(object);
System.out.println("Reading ObjectMessage:");
System.out.println(" " + (String) objectMessage.getObject());
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
SampleUtilities.exit(exitResult);
}
}
Creates and then reads a StreamMessage and a BytesMessage
/*
* @(#)MessageConversion.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The MessageConversion class consists only of a main method, which creates
* and then reads a StreamMessage and a BytesMessage. It does not send the
* messages.
* <p>
* The program demonstrates type conversions in StreamMessages: you can write
* data as a String and read it as an Int, and vice versa. The program also
* calls clearBody() to clear the message so that it can be rewritten.
* <p>
* The program also shows how to write and read a BytesMessage using data types
* other than a byte array. Conversion between String and other types is
* not supported.
* <p>
* Before it can read a BytesMessage or StreamMessage that has not been sent,
* the program must call reset() to put the message body in read-only mode
* and reposition the stream.
*
* @author Kim Haase
* @version 1.4, 08/09/00
*/
public class MessageConversion {
/**
* Main method. Takes no arguments.
*/
public static void main(String[] args) {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
BytesMessage bytesMessage = null;
StreamMessage streamMessage = null;
int exitResult = 0;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
try {
/*
* Create a StreamMessage and write values of various data types
* to it.
* Reset the message, then read the values as Strings.
* Values written to a StreamMessage as one data type can be read
* as Strings and vice versa (except for String to char conversion).
*/
streamMessage = session.createStreamMessage();
streamMessage.writeBoolean(false);
streamMessage.writeDouble(123.456789e222);
streamMessage.writeInt(223344);
streamMessage.writeChar("q");
streamMessage.reset();
System.out.println("Reading StreamMessage items of various data"
+ " types as String:");
System.out.println(" Boolean: " + streamMessage.readString());
System.out.println(" Double: " + streamMessage.readString());
System.out.println(" Int: " + streamMessage.readString());
System.out.println(" Char: " + streamMessage.readString());
/*
* Clear the body of the StreamMessage and write several Strings
* to it.
* Reset the message and read the values back as other data types.
*/
streamMessage.clearBody();
streamMessage.writeString("true");
streamMessage.writeString("123.456789e111");
streamMessage.writeString("556677");
// Not char: String to char conversion isn"t valid
streamMessage.reset();
System.out.println("Reading StreamMessage String items as other"
+ " data types:");
System.out.println(" Boolean: " + streamMessage.readBoolean());
System.out.println(" Double: " + streamMessage.readDouble());
System.out.println(" Int: " + streamMessage.readInt());
/*
* Create a BytesMessage and write values of various types into
* it.
*/
bytesMessage = session.createBytesMessage();
bytesMessage.writeBoolean(false);
bytesMessage.writeDouble(123.456789e22);
bytesMessage.writeInt(778899);
bytesMessage.writeInt(0x7f800000);
bytesMessage.writeChar("z");
/*
* Reset the message and read the values back. Only limited
* type conversions are possible.
*/
bytesMessage.reset();
System.out.println("Reading BytesMessages of various types:");
System.out.println(" Boolean: " + bytesMessage.readBoolean());
System.out.println(" Double: " + bytesMessage.readDouble());
System.out.println(" Int: " + bytesMessage.readInt());
System.out.println(" Float: " + bytesMessage.readFloat());
System.out.println(" Char: " + bytesMessage.readChar());
} catch (JMSException e) {
System.out.println("JMS Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
SampleUtilities.exit(exitResult);
}
}
Creates a Producer and a Consumer objects (Producer and Consumer classes are defined in this file)
/*
* @(#)XMLMessageExample.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.io.*;
import javax.jms.*;
import org.w3c.dom.Document;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* The XMLMessageExample class consists a main method which creates a
* Producer and a Consumer objects (Producer and Consumer classes are defined
* in this file). The Producer reads a XML file to a StreamMessage and sends
* it to a queue. The Consumer receives the StreamMessage and read the XML
* document from it then using JAXP API to parse the XML document into a
* DOM object.
* <p>
* The command line options for running this program include (in order)
* a Sun Java(tm) System Message Queue Queue name
* an XML filename (sample.xml and its DTD file - sample.dtd are provided)
* an optional system ID URL (for use by the XML parser to resolve any
* external entity URI)
*
*/
public class XMLMessageExample {
/**
* Main method.
*
* @param args the queue used by the example
* the xml filename used by the example
* and optionally, the system identifier
*/
public static void main(String[] args) {
if ( (args.length < 2) || (args.length > 3) ) {
System.out.println("Usage: java XMLMessageExample "
+ "<queue_name> <xml_filename> [<systemid_url>]");
System.exit(1);
}
String queueName = new String(args[0]);
System.out.println("Queue name is " + queueName);
Producer producer = null;
Consumer consumer = null;
try {
producer = new Producer(queueName);
consumer = new Consumer(queueName);
producer.send(args[1]);
consumer.receive(args.length > 2 ? args[2]:null);
}
catch (Exception e) {
System.out.println("Exception occurred : " + e.toString());
e.printStackTrace();
}
finally {
if (producer != null) producer.close();
if (consumer != null) consumer.close();
}
}
}
class Producer {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageProducer msgProducer = null;
public Producer(String queueName) throws Exception {
try {
connectionFactory = SampleUtilities.getConnectionFactory();
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
msgProducer = session.createProducer(queue);
}
catch (Exception e) {
close();
throw e;
}
}
public void close() {
if (connection != null) {
try {
connection.close();
connection = null;
} catch (JMSException e) {}
}
}
public void send(String xmlfile) throws Exception {
StreamMessage streamMessage = null;
/*
* Create input stream from the xml file
* Read bytes from the input stream into a buffer
* and construct a StreamMessage
* Send the message
*/
File f = new File(xmlfile);
int length = (int)f.length();
FileInputStream inStream = new FileInputStream(f);
byte[] buf = new byte[length];
inStream.read(buf);
inStream.close();
streamMessage = session.createStreamMessage();
streamMessage.writeObject(buf);
System.out.println("Write " + length + " bytes into message");
/*
* Set a property so that the consumer can check to know
* this message has a XML document body. This is helpful
* if there are other messages in the queue.
*/
streamMessage.setBooleanProperty("MyXMLMessage", true);
msgProducer.send(streamMessage);
}
}
class Consumer {
DocumentBuilder docBuilder = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageConsumer msgConsumer = null;
public Consumer(String queueName) throws Exception {
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilder = docBuilderFactory.newDocumentBuilder();
connectionFactory = SampleUtilities.getConnectionFactory();
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
msgConsumer = session.createConsumer(queue);
connection.start();
}
catch (Exception e) {
close();
throw e;
}
}
public void close() {
if (connection != null) {
try {
connection.close();
connection = null;
} catch (JMSException ee) {}
}
}
public void receive(String systemid) throws Exception {
StreamMessage streamMessage = null;
Message message = null;
/*
* Receive the message from the queue
* Process the message
*/
while(true) {
message = msgConsumer.receive();
if (!(message instanceof StreamMessage)) {
//not our XML message
continue;
}
streamMessage = (StreamMessage)message;
try {
if (!streamMessage.getBooleanProperty("MyXMLMessage")) {
//not our XML message
continue;
}
} catch (NullPointerException e) { //the property not exist
//not our XML message
continue;
}
//got our XML message
byte[] bytes = (byte[])streamMessage.readObject();
System.out.println("Read " + bytes.length + " bytes from message");
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
InputSource is =new InputSource(bais);
if (systemid != null) {
is.setSystemId(systemid);
}
parse(is);
break;
}
}
private void parse(InputSource is) throws Exception {
try {
Document doc = docBuilder.parse(is);
// normalize text representation
doc.getDocumentElement().normalize();
System.out.println ("Root element of the doc is " +
doc.getDocumentElement().getNodeName());
} catch (SAXParseException e) {
System.out.println ("** Parsing error"
+ ", line " + e.getLineNumber()
+ ", uri " + e.getSystemId());
System.out.println(" " + e.getMessage());
Exception x = e.getException();
((x == null) ? e : x).printStackTrace();
throw e;
} catch (SAXException e) {
Exception x = e.getException();
((x == null) ? e : x).printStackTrace();
throw e;
}
}
}
Demonstrates a simple end-to-end "Hello World" JMS example that can be compiled and run with the Sun Java(tm) System Message Queue product
/*
* @(#)HelloWorldMessageJNDI.java 1.6 05/03/29
*
* Copyright (c) 2001-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
================================================================================
@(#)README 1.15 08/04/05
================================================================================
HelloWorldMessageJNDI example
Description
-----------
This example demonstrates a simple end-to-end "Hello World" JMS example that
can be compiled and run with the Sun Java(tm) System Message Queue product. The
test program uses Java Naming and Directory Interface (JNDI) to lookup
administered objects, sends and receives a JMS "Hello World" message via a Queue
destination.
This example is also the companion example used in the "Administration Console
Tutorial" (Chapter 4 of the MQ Administrator"s Guide). The "Administration
Console Tutorial" focuses more on the Administration Console GUI; this README
contains instructions that use the command line tool imqobjmgr.
This example demonstrates the following:
- How to create and store MQ administered objects in a file based object
store using the MQ imqobjmgr tool.
- A simple "Hello World" JMS Application:
- How to use the JNDI APIs to lookup MQ administered objects in a file
based object store.
- Sending and receiving JMS messages.
- How to compile the JMS application.
- How to run the JMS application.
Files
-----
HelloWorldMessageJNDI.java Source file for this example.
*.class Prebuilt Java class files for this example.
add_cf.props imqobjmgr command file for creating
Connection Factory object.
add_q.props imqobjmgr command file for creating
Queue object.
delete_cf.props imqobjmgr command file for deleting
Connection Factory object.
delete_q.props imqobjmgr command file for deleting
Queue object.
list.props imqobjmgr command file for listing MQ
administered objects.
README This file.
JMS/MQ background
-----------------
Every JMS application that sends and/or receives messages needs access to at
least 2 JMS administered objects:
Connection Factory object
Destination object
The Connection Factory object is used by the application to connect to the JMS
provider (MQ broker). The Destination object is used to identify the relevant
destination on the JMS provider, for example when sending or receiving messages.
Each JMS provider (like MQ) has it"s own implementation of the above objects
which encapsulate provider-specific implementation and configuration
information.
This example uses the Queue messaging domain which means that the specific
object types the example will deal with are:
Connection Factory object (javax.jms.ConnectionFactory)
Queue Destination object (javax.jms.Queue)
The above 2 objects can be directly instantiated by the JMS application. For
example:
cf = new com.sun.messaging.ConnectionFactory();
(com.sun.messaging.ConnectionFactory is an object that is of type
javax.jms.ConnectionFactory)
However, this makes the application not portable across JMS vendors. To make
a JMS application truly portable, the objects should be stored in an object
store and JNDI should be used to look them up. The fact that the objects used
here are MQ specific will be completely transparent to the application if JNDI
is used. These objects can also be shared by multiple applications that need
access to the same MQ brokers and destinations.
Having all the JMS applications use administered objects in one object store
also makes management a little easier - compare this to the case where every JMS
application each instantiated it"s own administered objects; managing which MQ
broker or destination each application uses can become difficult as the
complexity and size of the application grows.
MQ provides the object manager utility/tool (imqobjmgr) to manage (add, delete,
list, query, or update) MQ administered objects in an object store. To create
an administered object, imqobjmgr accepts the following information:
- The command/action that is needed: add
- The type of object in question e.g. Topic, Queue, Connection Factory,
etc.
- Attributes/properties of the object.
- Location of object store. This is specified as JNDI properties.
- JNDI lookupname of object in object store
Details on how the above information is specified to imqobjmgr is explained in
the Sun Java(tm) System Message Queue Administrator"s Guide. It can also be seen
as part of imqobjmgr usage help:
imqobjmgr -H
To ease the running of this example, imqobjmgr command files will be used.
imqobjmgr allows you to specify the name of a command file that uses java
property file syntax to represent all or part of the imqobjmgr subcommand
clause. Using a command file with imqobjmgr is especially useful to specify
object store attributes, which are likely to be the same across multiple
invocations of imqobjmgr and which normally require a lot of typing. Command
files can help reduce errors caused by typos on the command line. Using a
command file can also allow you to avoid a situation in which you might
otherwise exceed the maximum number of characters allowed for the command line.
So instead of typing:
imqobjmgr add
-t q
-l "MyQueue"
-o "imqDestinationName=MyQueueDest"
-j java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
-j java.naming.provider.url=file:///C:/Temp
(all on one line)
you only need to type:
imqobjmgr -i add_q.props
(where add_q.props is a command file)
Each command file that is a part of this example will contain sufficient
documentation to show what the full imqobjmgr command line is required to
perform the equivalent action.
The format or syntax of the imqobjmgr command/input file is described in
the Sun Java(tm) System Message Queue Administrator"s Guide.
Specifying the object Store: JNDI Properties
--------------------------------------------
The imqobjmgr tool uses JNDI to manage the object store. The object store
is specified to imqobjmgr via various JNDI properties. The most commonly
used JNDI properties here are:
- java.naming.factory.initial (Initial Context Factory)
The initial context factory is used to specify which JNDI service
provider you wish to use for your object store; for example, the
file system, LDAP or some other JNDI service provider.
The value to use for a file system object store is:
com.sun.jndi.fscontext.RefFSContextFactory
The value to use for an LDAP based object store is:
com.sun.jndi.ldap.LdapCtxFactory
- java.naming.provider.url (Provider URL)
This is the property for specifying the URL or location of
your object store. The provider URL value is dependent on what
service provider was specified for java.naming.factory.initial.
For a file system object store, an example value for this is:
file:///C:/Temp
or
file:///tmp
The directory specified for a file system object store must
already exist and must be accessible by the application or
tool using it.
For an LDAP based object store, an example value for this is:
ldap://myldaphost:389/ou=mqobjs, o=myapplication
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
fscontext.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer"s Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:
/usr/share/lib/fscontext.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;
%IMQ_HOME%\lib\fscontext.jar:.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:/opt/sun/mq/share/lib/fscontext.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:/opt/sun/mq/share/lib/fscontext.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac HelloWorldMessageJNDI.java
Running the example
-------------------
Here are the steps for running this example:
1. Verify object store file location.
2. Create the Connection Factory administered object.
3. Create the Queue administered object.
4. Start the MQ broker.
5. Run the JMS application.
6. Cleanup
1. Verify object store file location
------------------------------------
This example uses the file system object store. The directory that
is used by default is C:/Temp. This is a path that is commonly
available on the Windows platform. This path is used as the value
for the JNDI provider URL for the object store. The provider URL
that is specified has the following syntax:
file:///C:/Temp
If this path is not available for use (for example, if you are running
on a Solaris machine), you need to:
- Modify the value of the objstore.attrs.java.naming.provider.url
property in all the imqobjmgr command files (*.props). They already
have a commented out entry that specifies the /tmp directory on
Solaris as an example of how to configure this property differently.
- (This is to be done later) Run the sample application with the new
provider URL for example:
java HelloWorldMessageJNDI file:///tmp
2. Create the Connection Factory administered object
----------------------------------------------------------
To create the connection factory object, run the following:
imqobjmgr -i add_cf.props
3. Create the Queue administered object
---------------------------------------
To create the queue object, run the following:
imqobjmgr -i add_q.props
Optional:
After creating the Connection Factory and Queue objects,
you can verify that they exist by listing them:
imqobjmgr -i list.props
4. Start the broker
-------------------
The command for starting the broker is:
imqbrokerd
Run the above command in a separate command (or terminal) window.
5. Run the JMS application
--------------------------
To run the sample application, run the following command:
java HelloWorldMessageJNDI
or
java HelloWorldMessageJNDI file:///tmp
if you need to specify an alternate provider URL (object store location).
As noted above, the default is file:///C:/Temp
You should see the following output:
Using file:///C:/Temp for Context.PROVIDER_URL
Looking up Connection Factory object with lookup
name: MyConnectionFactory
Connection Factory object found.
Looking up Queue object with lookup name: MyQueue
Queue object found.
Creating connection to broker.
Connection to broker created.
Publishing a message to Queue: MyQueueDest
Received the following message: Hello World
6. Cleanup
----------
Once you are done with the example, you can optionally delete the administered
objects created by running:
imqobjmgr -i delete_cf.props
imqobjmgr -i delete_q.props
You will be prompted for confirmation - respond with "y".
Useful URLs
-----------
MQ main product page:
http://sun.ru/software/message_queue
MQ documentation page:
http://docs.sun.ru/db/prod/s1.s1msgqu#hic
A better understanding of JNDI and how java objects are stored can be found
in the JNDI tutorial at:
http://java.sun.ru/products/jndi/tutorial/index.html
Some of the relevant sections of the JNDI tutorial:
Java Objects and the Directory
http://java.sun.ru/products/jndi/tutorial/objects/index.html
Tips for LDAP Users
http://java.sun.ru/products/jndi/tutorial/ldap/index.html
LDAP Security
http://java.sun.ru/products/jndi/tutorial/ldap/security/index.html
This will explain the usage of these properties:
java.naming.security.authentication
java.naming.security.principal
java.naming.security.credentials
/*
* @(#)HelloWorldMessageJNDI.java 1.6 05/03/29
*
* Copyright (c) 2001-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Simple message producer and consumer which obtains its ConnectionFactory
* and Queue from Administered Objects using a JNDI lookup.
*
* This example requires two administered objects to be stored before it
* will work.
*
* 1. A ConnectionFactory Object stored with a lookup name of
* ``MyConnectionFactory""
* 2. A Queue Object stored with a lookup name of ``MyQueue""
*
* The initial context factory is configured in this example to use the File
* Store (an alternative would be to use LDAP). The provider url (where
* the file store is located) is defined by default to be C:/Temp
* This is a Windows specific path.
* When running this example on Unix, the first command line parameter
* must be set to the Unix directory url where the File Store has been created.
* e.g. file:///tmp on Solaris/Linux.
*
* What this means is that an MQ Object Store should be created (via imqadmin
* or imqobjmgr) at C:/Temp. When that store is created the following JNDI
* Naming Service Properties should be set (via the imqadmin or imqobjmgr):
*
* java.naming.provider.url = file:///C:/Temp
* java.naming.factory.initial = com.sun.jndi.fscontext.RefFSContextFactory
*
* If this example is run on Solaris/Linux, use the following value instead
*
* java.naming.provider.url = file:///tmp
*
* If you have turned off auto-creation of destinations on the MQ broker
* then a physical Queue destination matching the destination name used
* in the queue administered object needs to be created on the broker.
* That is best accomplished by using the Administration Console.
*
* For this example to compile and run the following must be
* in your CLASSPATH (in addition to the directory containing this example):
*
* jms.jar, imq.jar, fscontext.jar (these are located in IMQ_HOME/lib)
*/
import javax.naming.*;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.MessageProducer;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.DeliveryMode;
import javax.jms.TextMessage;
import javax.jms.JMSException;
import java.util.*;
public class HelloWorldMessageJNDI {
static String def_windows_url = "file:///C:/Temp";
static String def_unix_url = "file:///tmp";
String MYCF_LOOKUP_NAME = "MyConnectionFactory";
String MYQUEUE_LOOKUP_NAME = "MyQueue";
ConnectionFactory cf;
Connection connection;
Session session;
MessageProducer msgProducer;
MessageConsumer msgConsumer;
Queue queue;
TextMessage msg,
rcvMsg;
public static void main(String args[]) {
String url = def_windows_url;
if (args.length > 0) {
url = args[0];
}
System.out.println("\nUsing "
+ url
+ " for Context.PROVIDER_URL");
HelloWorldMessageJNDI simple_client = new HelloWorldMessageJNDI(url);
}
public HelloWorldMessageJNDI(String url) {
Hashtable env;
Context ctx = null;
env = new Hashtable();
// Store the environment variables that tell JNDI which initial context
// to use and where to find the provider.
// For use with the File System JNDI Service Provider
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, url);
try {
// Create the initial context.
ctx = new InitialContext(env);
} catch (NamingException ne) {
System.err.println("Failed to create InitialContext.");
System.err.println("The Context.PROVIDER_URL used/specified was: " + url);
System.err.println("Please make sure that the path to the above URL exists");
System.err.println("and matches with the objstore.attrs.java.naming.provider.url");
System.err.println("property value specified in the imqobjmgr command files:");
System.err.println("\tadd_cf.props");
System.err.println("\tadd_q.props");
System.err.println("\tdelete_cf.props");
System.err.println("\tdelete_q.props");
System.err.println("\tlist.props\n");
usage();
System.err.println("\nThe exception details:");
ne.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
// Lookup my connection factory from the admin object store.
// The name used here here must match the lookup name
// used when the admin object was stored.
System.out.println("Looking up Connection Factory object with lookup name: "
+ MYCF_LOOKUP_NAME);
cf = (javax.jms.ConnectionFactory) ctx.lookup(MYCF_LOOKUP_NAME);
System.out.println("Connection Factory object found.");
} catch (NamingException ne) {
System.err.println("Failed to lookup Connection Factory object.");
System.err.println("Please make sure you have created the Connection Factory object using the command:");
System.err.println("\timqobjmgr -i add_cf.props");
System.err.println("\nThe exception details:");
ne.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
// Lookup my queue from the admin object store.
// The name I search for here must match the lookup name used when
// the admin object was stored.
System.out.println("Looking up Queue object with lookup name: "
+ MYQUEUE_LOOKUP_NAME);
queue = (javax.jms.Queue)ctx.lookup(MYQUEUE_LOOKUP_NAME);
System.out.println("Queue object found.");
} catch (NamingException ne) {
System.err.println("Failed to lookup Queue object.");
System.err.println("Please make sure you have created the Queue object using the command:");
System.err.println("\timqobjmgr -i add_q.props");
System.err.println("\nThe exception details:");
ne.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
System.out.println("Creating connection to broker.");
connection = cf.createConnection();
System.out.println("Connection to broker created.");
} catch (JMSException e) {
System.err.println("Failed to create connection.");
System.err.println("Please make sure that the broker was started.");
System.err.println("\nThe exception details:");
e.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the MessageProducer and MessageConsumer
msgProducer = session.createProducer(queue);
msgConsumer = session.createConsumer(queue);
// Tell the provider to start sending messages.
connection.start();
msg = session.createTextMessage("Hello World");
// Publish the message
System.out.println("Publishing a message to Queue: " + queue.getQueueName());
msgProducer.send(msg, DeliveryMode.NON_PERSISTENT, 4, 0);
// Wait for it to be sent back.
rcvMsg = (TextMessage) msgConsumer.receive();
System.out.println("Received the following message: " + rcvMsg.getText());
connection.close();
} catch (JMSException e) {
System.err.println("JMS Exception: " + e);
e.printStackTrace();
System.exit(-1);
}
}
private static void usage() {
System.err.println("Usage: " +
"\tjava HelloWorldMessageJNDI [Context.PROVIDER_URL]\n" +
"\nOn Unix:\n\tjava HelloWorldMessageJNDI " + def_unix_url +
"\nOn Windows:\n\tjava HelloWorldMessageJNDI " + def_windows_url);
}
}
Demonstrates that mutable objects are copied, not passed by reference, when you use them to create message objects
/*
* @(#)ObjectMessages.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The ObjectMessages class consists only of a main method, which demonstrates
* that mutable objects are copied, not passed by reference, when you use them
* to create message objects.
* <p>
* The example uses only an ObjectMessage and a BytesMessage, but the same is
* true for all message formats.
*
* @author Kim Haase
* @version 1.4, 08/09/00
*/
public class ObjectMessages {
/**
* Main method. Takes no arguments.
*/
public static void main(String[] args) {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
ObjectMessage objectMessage = null;
String object = "A String is an object.";
BytesMessage bytesMessage = null;
byte[] byteArray = {3, 5, 7, 9, 11};
final int ARRLEN = 5;
int length = 0;
byte[] inByteData = new byte[ARRLEN];
int exitResult = 0;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
try {
/*
* Create an ObjectMessage from a String.
* Modify the original object.
* Read the message, proving that the object in the message
* has not changed.
*/
objectMessage = session.createObjectMessage();
System.out.println("Writing ObjectMessage with string: " + object);
objectMessage.setObject(object);
object = "I"m a different String now.";
System.out.println("Changed string; object is now: " + object);
System.out.println("ObjectMessage contains: " +
(String) objectMessage.getObject());
/*
* Create a BytesMessage from an array.
* Modify an element of the original array.
* Reset and read the message, proving that contents of the message
* have not changed.
*/
bytesMessage = session.createBytesMessage();
System.out.print("Writing BytesMessage with array: ");
for (int i = 0; i < ARRLEN; i++) {
System.out.print(" " + byteArray[i]);
}
System.out.println();
bytesMessage.writeBytes(byteArray);
byteArray[1] = 13;
System.out.print("Changed array element; array is now: ");
for (int i = 0; i < ARRLEN; i++) {
System.out.print(" " + byteArray[i]);
}
System.out.println();
bytesMessage.reset();
length = bytesMessage.readBytes(inByteData);
System.out.print("BytesMessage contains: ");
for (int i = 0; i < length; i++) {
System.out.print(" " + inByteData[i]);
}
System.out.println();
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
SampleUtilities.exit(exitResult);
}
}
Demonstrates the use of transactions in a JMS application
/*
* @(#)TransactedExample.java 1.4 04/09/15
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.util.Random;
import java.util.Hashtable;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.MessageProducer;
import javax.jms.MessageConsumer;
import javax.jms.Message;
import javax.jms.MapMessage;
import javax.jms.MessageListener;
import javax.jms.JMSException;
/**
* The TransactedExample class demonstrates the use of transactions in a JMS
* application. It represents a highly simplified eCommerce application, in
* which the following things happen:
*
* <pre>
* Legend
* R - Retailer
* V - Vendor
* S - Supplier
* O - Order Queue
* C - Confirmation Queue
* ()- Thread
* []- Queue
*
* 2(b) 3
* 1 2(a) /+------->[S1 O]<-----------(S1)
* /+-->[V O]<----+ / |
* / \ / 3 |
* / \ / 5 v------------------+
* (R) ( V )-------->[V C] 4
* \ / \ ^------------------+
* \ / \ |
* \ 7 6 / \ |
* +---->[R C]<--+ \ 2(c) 4 |
* +------->[SN O]<-----------(SN)
* </pre>
*
* <ol>
* <li>A retailer sends a message to the vendor order queue ordering a quantity
* of computers. It waits for the vendor"s reply.
* <li>The vendor receives the retailer"s order message and places an order
* message into each of its suppliers" order queues, all in one transaction.
* This JMS transaction combines one synchronous receive with multiple sends.
* <li>One supplier receives the order from its order queue, checks its
* inventory, and sends the items ordered to the order message"s replyTo
* field. If it does not have enough in stock, it sends what it has.
* The synchronous receive and the send take place in one JMS transaction.
* <li>The other supplier receives the order from its order queue, checks its
* inventory, and sends the items ordered to the order message"s replyTo
* field. If it does not have enough in stock, it sends what it has.
* The synchronous receive and the send take place in one JMS transaction.
* <li>The vendor receives the replies from the suppliers from its confirmation
* queue and updates the state of the order. Messages are processed by an
* asynchronous message listener; this step illustrates using JMS transactions
* with a message listener.
* <li>When all outstanding replies are processed for a given order, the vendor
* sends a message notifying the retailer whether or not it can fulfill the
* order.
* <li>The retailer receives the message from the vendor.
* </ol>
* <p>
* The program contains five classes: Retailer, Vendor, GenericSupplier,
* VendorMessageListener, and Order. It also contains a main method and a
* method that runs the threads of the Retail, Vendor, and two supplier classes.
* <p>
* All the messages use the MapMessage message type. Synchronous receives are
* used for all message reception except for the case of the vendor processing
* the replies of the suppliers. These replies are processed asynchronously
* and demonstrate how to use transactions within a message listener.
* <p>
* All classes except Retailer use transacted sessions.
* <p>
* The program uses five queues. Before you run the program, create the
* queues and name them A, B, C, D and E.
* <p>
* When you run the program, specify on the command line the number of
* computers to be ordered.
*
* @author Kim Haase
* @author Joseph Fialli
* @version 1.3, 08/18/00
*/
public class TransactedExample {
public static String vendorOrderQueueName = null;
public static String retailerConfirmationQueueName = null;
public static String monitorOrderQueueName = null;
public static String storageOrderQueueName = null;
public static String vendorConfirmationQueueName = null;
public static int exitResult = 0;
/**
* The Retailer class orders a number of computers by sending a message
* to a vendor. It then waits for the order to be confirmed.
* <p>
* In this example, the Retailer places two orders, one for the quantity
* specified on the command line and one for twice that number.
* <p>
* This class does not use transactions.
*
* @author Kim Haase
* @author Joseph Fialli
* @version 1.3, 08/18/00
*/
public static class Retailer extends Thread {
int quantity = 0;
/**
* Constructor. Instantiates the retailer with the quantity of
* computers being ordered.
*
* @param q the quantity specified in the program arguments
*/
public Retailer(int q) {
quantity = q;
}
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue vendorOrderQueue = null;
Queue retailerConfirmationQueue = null;
MessageProducer msgProducer = null;
MapMessage outMessage = null;
MessageConsumer orderConfirmationConsumer = null;
MapMessage inMessage = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
vendorOrderQueue =
SampleUtilities.getQueue(vendorOrderQueueName, session);
retailerConfirmationQueue =
SampleUtilities.getQueue(retailerConfirmationQueueName,
session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
System.out.println("Program assumes five queues named A B C D E");
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create non-transacted session and sender for vendor order
* queue.
* Create message to vendor, setting item and quantity values.
* Send message.
* Create receiver for retailer confirmation queue.
* Get message and report result.
* Send an end-of-message-stream message so vendor will
* stop processing orders.
*/
try {
msgProducer = session.createProducer(vendorOrderQueue);
outMessage = session.createMapMessage();
outMessage.setString("Item", "Computer(s)");
outMessage.setInt("Quantity", quantity);
outMessage.setJMSReplyTo(retailerConfirmationQueue);
msgProducer.send(outMessage);
System.out.println("Retailer: ordered " + quantity
+ " computer(s)");
orderConfirmationConsumer =
session.createConsumer(retailerConfirmationQueue);
connection.start();
inMessage = (MapMessage) orderConfirmationConsumer.receive();
if (inMessage.getBoolean("OrderAccepted") == true) {
System.out.println("Retailer: Order filled");
} else {
System.out.println("Retailer: Order not filled");
}
System.out.println("Retailer: placing another order");
outMessage.setInt("Quantity", quantity * 2);
msgProducer.send(outMessage);
System.out.println("Retailer: ordered "
+ outMessage.getInt("Quantity")
+ " computer(s)");
inMessage =
(MapMessage) orderConfirmationConsumer.receive();
if (inMessage.getBoolean("OrderAccepted") == true) {
System.out.println("Retailer: Order filled");
} else {
System.out.println("Retailer: Order not filled");
}
// Send a non-text control message indicating end of messages.
msgProducer.send(session.createMessage());
} catch (Exception e) {
System.out.println("Retailer: Exception occurred: "
+ e.toString());
e.printStackTrace();
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The Vendor class uses one transaction to receive the computer order from
* the retailer and order the needed number of monitors and disk drives
* from its suppliers. At random intervals, it throws an exception to
* simulate a database problem and cause a rollback.
* <p>
* The class uses an asynchronous message listener to process replies from
* suppliers. When all outstanding supplier inquiries complete, it sends a
* message to the Retailer accepting or refusing the order.
*
* @author Kim Haase
* @author Joseph Fialli
* @version 1.3, 08/18/00
*/
public static class Vendor extends Thread {
Random rgen = new Random();
int throwException = 1;
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Session asyncSession = null;
Queue vendorOrderQueue = null;
Queue monitorOrderQueue = null;
Queue storageOrderQueue = null;
Queue vendorConfirmationQueue = null;
MessageConsumer vendorOrderMessageConsumer = null;
MessageProducer monitorOrderMessageProducer = null;
MessageProducer storageOrderMessageProducer = null;
MapMessage orderMessage = null;
MessageConsumer vendorConfirmationMessageConsumer = null;
VendorMessageListener listener = null;
Message inMessage = null;
MapMessage vendorOrderMessage = null;
Message endOfMessageStream = null;
Order order = null;
int quantity = 0;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(true, 0);
asyncSession = connection.createSession(true, 0);
vendorOrderQueue =
SampleUtilities.getQueue(vendorOrderQueueName, session);
monitorOrderQueue =
SampleUtilities.getQueue(monitorOrderQueueName, session);
storageOrderQueue =
SampleUtilities.getQueue(storageOrderQueueName, session);
vendorConfirmationQueue =
SampleUtilities.getQueue(vendorConfirmationQueueName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
System.out.println("Program assumes six queues named A B C D E F");
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
try {
/*
* Create receiver for vendor order queue, sender for
* supplier order queues, and message to send to suppliers.
*/
vendorOrderMessageConsumer =
session.createConsumer(vendorOrderQueue);
monitorOrderMessageProducer =
session.createProducer(monitorOrderQueue);
storageOrderMessageProducer =
session.createProducer(storageOrderQueue);
orderMessage = session.createMapMessage();
/*
* Configure an asynchronous message listener to process
* supplier replies to inquiries for parts to fill order.
* Start delivery.
*/
vendorConfirmationMessageConsumer =
asyncSession.createConsumer(vendorConfirmationQueue);
listener = new VendorMessageListener(asyncSession, 2);
vendorConfirmationMessageConsumer.setMessageListener(listener);
connection.start();
/*
* Process orders in vendor order queue.
* Use one transaction to receive order from order queue
* and send messages to suppliers" order queues to order
* components to fulfill the order placed with the vendor.
*/
while (true) {
try {
// Receive an order from a retailer.
inMessage = vendorOrderMessageConsumer.receive();
if (inMessage instanceof MapMessage) {
vendorOrderMessage = (MapMessage) inMessage;
} else {
/*
* Message is an end-of-message-stream message from
* retailer. Send similar messages to suppliers,
* then break out of processing loop.
*/
endOfMessageStream = session.createMessage();
endOfMessageStream.setJMSReplyTo(vendorConfirmationQueue);
monitorOrderMessageProducer.send(endOfMessageStream);
storageOrderMessageProducer.send(endOfMessageStream);
session.rumit();
break;
}
/*
* A real application would check an inventory database
* and order only the quantities needed. Throw an
* exception every few times to simulate a database
* concurrent-access exception and cause a rollback.
*/
if (rgen.nextInt(3) == throwException) {
throw new JMSException("Simulated database concurrent access exception");
}
// Record retailer order as a pending order.
order = new Order(vendorOrderMessage);
/*
* Set order number and reply queue for outgoing
* message.
*/
orderMessage.setInt("VendorOrderNumber",
order.orderNumber);
orderMessage.setJMSReplyTo(vendorConfirmationQueue);
quantity = vendorOrderMessage.getInt("Quantity");
System.out.println("Vendor: Retailer ordered " +
quantity + " " +
vendorOrderMessage.getString("Item"));
// Send message to monitor supplier.
orderMessage.setString("Item", "Monitor");
orderMessage.setInt("Quantity", quantity);
monitorOrderMessageProducer.send(orderMessage);
System.out.println("Vendor: ordered " + quantity + " "
+ orderMessage.getString("Item")
+ "(s)");
/*
* Reuse message to send to storage supplier, changing
* only item name.
*/
orderMessage.setString("Item", "Hard Drive");
storageOrderMessageProducer.send(orderMessage);
System.out.println("Vendor: ordered " + quantity + " "
+ orderMessage.getString("Item")
+ "(s)");
// Commit session.
session.rumit();
System.out.println(" Vendor: committed transaction 1");
} catch(JMSException e) {
System.out.println("Vendor: JMSException occurred: "
+ e.toString());
e.printStackTrace();
session.rollback();
System.out.println(" Vendor: rolled back transaction 1");
exitResult = 1;
}
}
// Wait till suppliers get back with answers.
listener.monitor.waitTillDone();
} catch (JMSException e) {
System.out.println("Vendor: Exception occurred: " +
e.toString());
e.printStackTrace();
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The Order class represents a Retailer order placed with a Vendor.
* It maintains a table of pending orders.
*
* @author Joseph Fialli
* @version 1.3, 08/18/00
*/
public static class Order {
private static Hashtable pendingOrders = new Hashtable();
private static int nextOrderNumber = 1;
private static final int PENDING_STATUS = 1;
private static final int CANCELLED_STATUS = 2;
private static final int FULFILLED_STATUS = 3;
int status;
public final int orderNumber;
public int quantity;
public final MapMessage order; // original order from retailer
public MapMessage monitor = null; // reply from supplier
public MapMessage storage = null; // reply from supplier
/**
* Returns the next order number and increments the static variable
* that holds this value.
*
* @return the next order number
*/
private static int getNextOrderNumber() {
int result = nextOrderNumber;
nextOrderNumber++;
return result;
}
/**
* Constructor. Sets order number; sets order and quantity from
* incoming message. Sets status to pending, and adds order to hash
* table of pending orders.
*
* @param order the message containing the order
*/
public Order(MapMessage order) {
this.orderNumber = getNextOrderNumber();
this.order = order;
try {
this.quantity = order.getInt("Quantity");
} catch (JMSException je) {
System.err.println("Unexpected error. Message missing Quantity");
this.quantity = 0;
}
status = PENDING_STATUS;
pendingOrders.put(new Integer(orderNumber), this);
}
/**
* Returns the number of orders in the hash table.
*
* @return the number of pending orders
*/
public static int outstandingOrders() {
return pendingOrders.size();
}
/**
* Returns the order corresponding to a given order number.
*
* @param orderNumber the number of the requested order
* @return the requested order
*/
public static Order getOrder(int orderNumber) {
return (Order) pendingOrders.get(new Integer(orderNumber));
}
/**
* Called by the onMessage method of the VendorMessageListener class
* to process a reply from a supplier to the Vendor.
*
* @param component the message from the supplier
* @return the order with updated status information
*/
public Order processSubOrder(MapMessage component) {
String itemName = null;
// Determine which subcomponent this is.
try {
itemName = component.getString("Item");
} catch (JMSException je) {
System.err.println("Unexpected exception. Message missing Item");
}
if (itemName.rupareTo("Monitor") == 0) {
monitor = component;
} else if (itemName.rupareTo("Hard Drive") == 0 ) {
storage = component;
}
/*
* If notification for all subcomponents has been received,
* verify the quantities to compute if able to fulfill order.
*/
if ( (monitor != null) && (storage != null) ) {
try {
if (quantity > monitor.getInt("Quantity")) {
status = CANCELLED_STATUS;
} else if (quantity > storage.getInt("Quantity")) {
status = CANCELLED_STATUS;
} else {
status = FULFILLED_STATUS;
}
} catch (JMSException je) {
System.err.println("Unexpected exception " + je);
status = CANCELLED_STATUS;
}
/*
* Processing of order is complete, so remove it from
* pending-order list.
*/
pendingOrders.remove(new Integer(orderNumber));
}
return this;
}
/**
* Determines if order status is pending.
*
* @return true if order is pending, false if not
*/
public boolean isPending() {
return status == PENDING_STATUS;
}
/**
* Determines if order status is cancelled.
*
* @return true if order is cancelled, false if not
*/
public boolean isCancelled() {
return status == CANCELLED_STATUS;
}
/**
* Determines if order status is fulfilled.
*
* @return true if order is fulfilled, false if not
*/
public boolean isFulfilled() {
return status == FULFILLED_STATUS;
}
}
/**
* The VendorMessageListener class processes an order confirmation message
* from a supplier to the vendor.
* <p>
* It demonstrates the use of transactions within message listeners.
*
* @author Joseph Fialli
* @version 1.3, 08/18/00
*/
public static class VendorMessageListener implements MessageListener {
final SampleUtilities.DoneLatch monitor =
new SampleUtilities.DoneLatch();
private final Session session;
int numSuppliers;
/**
* Constructor. Instantiates the message listener with the session
* of the consuming class (the vendor).
*
* @param session the session of the consumer
* @param numSuppliers the number of suppliers
*/
public VendorMessageListener(Session session, int numSuppliers) {
this.session = session;
this.numSuppliers = numSuppliers;
}
/**
* Casts the message to a MapMessage and processes the order.
* A message that is not a MapMessage is interpreted as the end of the
* message stream, and the message listener sets its monitor state to
* all done processing messages.
* <p>
* Each message received represents a fulfillment message from
* a supplier.
*
* @param message the incoming message
*/
public void onMessage(Message message) {
/*
* If message is an end-of-message-stream message and this is the
* last such message, set monitor status to all done processing
* messages and commit transaction.
*/
if (! (message instanceof MapMessage)) {
if (Order.outstandingOrders() == 0) {
numSuppliers--;
if (numSuppliers == 0) {
monitor.allDone();
}
}
try {
session.rumit();
} catch (JMSException je) {}
return;
}
/*
* Message is an order confirmation message from a supplier.
*/
int orderNumber = -1;
try {
MapMessage component = (MapMessage) message;
/*
* Process the order confirmation message and commit the
* transaction.
*/
orderNumber = component.getInt("VendorOrderNumber");
Order order =
Order.getOrder(orderNumber).processSubOrder(component);
session.rumit();
/*
* If this message is the last supplier message, send message
* to Retailer and commit transaction.
*/
if (! order.isPending()) {
System.out.println("Vendor: Completed processing for order "
+ order.orderNumber);
Queue replyQueue = (Queue) order.order.getJMSReplyTo();
MessageProducer mp = session.createProducer(replyQueue);
MapMessage retailerConfirmationMessage =
session.createMapMessage();
if (order.isFulfilled()) {
retailerConfirmationMessage.setBoolean("OrderAccepted",
true);
System.out.println("Vendor: sent " + order.quantity
+ " computer(s)");
} else if (order.isCancelled()) {
retailerConfirmationMessage.setBoolean("OrderAccepted",
false);
System.out.println("Vendor: unable to send " +
order.quantity + " computer(s)");
}
mp.send(retailerConfirmationMessage);
session.rumit();
System.out.println(" Vendor: committed transaction 2");
}
} catch (JMSException je) {
je.printStackTrace();
try {
session.rollback();
} catch (JMSException je2) {}
} catch (Exception e) {
e.printStackTrace();
try {
session.rollback();
} catch (JMSException je2) {}
}
}
}
/**
* The GenericSupplier class receives an item order from the
* vendor and sends a message accepting or refusing it.
*
* @author Kim Haase
* @author Joseph Fialli
* @version 1.3, 08/18/00
*/
public static class GenericSupplier extends Thread {
final String PRODUCT_NAME;
final String IN_ORDER_QUEUE;
int quantity = 0;
/**
* Constructor. Instantiates the supplier as the supplier for the
* kind of item being ordered.
*
* @param itemName the name of the item being ordered
* @param inQueue the queue from which the order is obtained
*/
public GenericSupplier(String itemName, String inQueue) {
PRODUCT_NAME = itemName;
IN_ORDER_QUEUE = inQueue;
}
/**
* Checks to see if there are enough items in inventory.
* Rather than go to a database, it generates a random number related
* to the order quantity, so that some of the time there won"t be
* enough in stock.
*
* @return the number of items in inventory
*/
public int checkInventory() {
Random rgen = new Random();
return (rgen.nextInt(quantity * 5));
}
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue orderQueue = null;
MessageConsumer msgConsumer = null;
Message inMessage = null;
MapMessage orderMessage = null;
MapMessage outMessage = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(true, 0);
orderQueue =
SampleUtilities.getQueue(IN_ORDER_QUEUE, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
System.out.println("Program assumes six queues named A B C D E F");
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
// Create receiver for order queue and start message delivery.
try {
msgConsumer = session.createConsumer(orderQueue);
connection.start();
} catch (JMSException je) {
exitResult = 1;
}
/*
* Keep checking supplier order queue for order request until
* end-of-message-stream message is received.
* Receive order and send an order confirmation as one transaction.
*/
while (true) {
try {
inMessage = msgConsumer.receive();
if (inMessage instanceof MapMessage) {
orderMessage = (MapMessage) inMessage;
} else {
/*
* Message is an end-of-message-stream message.
* Send a similar message to reply queue, commit
* transaction, then stop processing orders by breaking
* out of loop.
*/
MessageProducer msgProducer =
session.createProducer((Queue) inMessage.getJMSReplyTo());
msgProducer.send(session.createMessage());
session.rumit();
break;
}
// Extract quantity ordered from order message.
quantity = orderMessage.getInt("Quantity");
System.out.println(PRODUCT_NAME
+ " Supplier: Vendor ordered " + quantity + " "
+ orderMessage.getString("Item") + "(s)");
/*
* Create sender and message for reply queue.
* Set order number and item; check inventory and set
* quantity available.
* Send message to vendor and commit transaction.
*/
MessageProducer msgProducer =
session.createProducer((Queue) orderMessage.getJMSReplyTo());
outMessage = session.createMapMessage();
outMessage.setInt("VendorOrderNumber",
orderMessage.getInt("VendorOrderNumber"));
outMessage.setString("Item", PRODUCT_NAME);
int numAvailable = checkInventory();
if (numAvailable >= quantity) {
outMessage.setInt("Quantity", quantity);
} else {
outMessage.setInt("Quantity", numAvailable);
}
msgProducer.send(outMessage);
System.out.println(PRODUCT_NAME + " Supplier: sent "
+ outMessage.getInt("Quantity") + " "
+ outMessage.getString("Item") + "(s)");
session.rumit();
System.out.println(" " + PRODUCT_NAME
+ " Supplier: committed transaction");
} catch (Exception e) {
System.out.println(PRODUCT_NAME
+ " Supplier: Exception occurred: " + e.toString());
e.printStackTrace();
exitResult = 1;
}
}
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
/**
* Creates the Retailer and Vendor classes and the two supplier classes,
* then starts the threads.
*
* @param quantity the quantity specified on the command line
*/
public static void run_threads(int quantity) {
Retailer r = new Retailer(quantity);
Vendor v = new Vendor();
GenericSupplier ms = new GenericSupplier("Monitor",
monitorOrderQueueName);
GenericSupplier ss = new GenericSupplier("Hard Drive",
storageOrderQueueName);
r.start();
v.start();
ms.start();
ss.start();
try {
r.join();
v.join();
ms.join();
ss.join();
} catch (InterruptedException e) {}
}
/**
* Reads the order quantity from the command line, then
* calls the run_threads method to execute the program threads.
*
* @param args the quantity of computers being ordered
*/
public static void main(String[] args) {
TransactedExample te = new TransactedExample();
int quantity = 0;
if (args.length != 1) {
System.out.println("Usage: java TransactedExample <integer>");
System.out.println("Program assumes five queues named A B C D E");
System.exit(1);
}
te.vendorOrderQueueName = new String("A");
te.retailerConfirmationQueueName = new String("B");
te.monitorOrderQueueName = new String("C");
te.storageOrderQueueName = new String("D");
te.vendorConfirmationQueueName = new String("E");
quantity = (new Integer(args[0])).intValue();
System.out.println("Quantity to be ordered is " + quantity);
if (quantity > 0) {
te.run_threads(quantity);
} else {
System.out.println("Quantity must be positive and nonzero");
te.exitResult = 1;
}
SampleUtilities.exit(te.exitResult);
}
}
Fetches one or more messages from a queue using asynchronous message delivery
/*
* @(#)AsynchQueueExample.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The AsynchQueueExample class consists only of a main method, which fetches
* one or more messages from a queue using asynchronous message delivery.
* <p>
* Compile TextListener.java before you run this program.
* <p>
* Run this program in conjunction with SenderToQueue. Specify a queue name
* on the command line when you run the program.
*
* @author Kim Haase
* @version 1.6, 08/14/00
*/
public class AsynchQueueExample {
/**
* Main method.
*
* @param args the queue used by the example
*/
public static void main(String[] args) {
String queueName = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageConsumer msgConsumer = null;
TextListener textListener = null;
int exitResult = 0;
if (args.length != 1) {
System.out.println("Usage: java AsynchQueueExample <queue_name>");
System.exit(1);
}
queueName = new String(args[0]);
System.out.println("Queue name is " + queueName);
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create consumer.
* Register message listener (TextListener).
* Start message delivery; listener displays the message obtained.
* Block until producer issues a control message indicating
* end of publish stream.
*/
try {
msgConsumer = session.createConsumer(queue);
textListener = new TextListener();
msgConsumer.setMessageListener(textListener);
connection.start();
textListener.monitor.waitTillDone();
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
SampleUtilities.exit(exitResult);
}
}
Fetches one or more messages from a queue using synchronous message delivery
/*
* @(#)SynchQueueExample.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The SynchQueueExample class consists only of a main method, which fetches
* one or more messages from a queue using synchronous message delivery. Run
* this program in conjunction with SenderToQueue. Specify a queue name on the
* command line when you run the program.
* <p>
* The program calls methods in the SampleUtilities class.
*
* @author Kim Haase
* @version 1.7, 08/14/00
*/
public class SynchQueueExample {
/**
* Main method.
*
* @param args the queue used by the example
*/
public static void main(String[] args) {
String queueName = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageConsumer msgConsumer = null;
TextMessage message = null;
int exitResult = 0;
/*
* Read queue name from command line and display it.
*/
if (args.length != 1) {
System.out.println("Usage: java SynchQueueExample <queue_name>");
System.exit(1);
}
queueName = new String(args[0]);
System.out.println("Queue name is " + queueName);
/*
* Obtain connection factory.
* Create connection.
* Create session from connection; false means session is not
* transacted.
* Obtain queue name.
*/
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create consumer, then start message delivery.
* Receive all text messages from queue until
* a non-text message is received indicating end of
* message stream.
* Close connection and exit.
*/
try {
msgConsumer = session.createConsumer(queue);
connection.start();
while (true) {
Message m = msgConsumer.receive();
if (m instanceof TextMessage) {
message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
} else {
// Non-text control message indicates end of messages.
break;
}
}
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
SampleUtilities.exit(exitResult);
}
}
How to write a GUI application that uses a JMS QueueBrowser to browse the contents of a queue
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
================================================================================
@(#)README 1.7 03/22/05
================================================================================
QueueBrowser example
Description
-----------
This example illustrates how to write a GUI application that uses a
JMS QueueBrowser to browse the contents of a queue. It also illustrates
the use of the Message Queue monitoring API to get the list of destinations
from the Message Queue broker.
Some basic info on this example:
- Subscribes to the "mq.metrics.detination_list" topic to get the
list of destinations from imqbrokerd and places them in a menu
(only works with EE edition).
- Creates a QueueBrowser for the particular queue specified.
- Lists messages on the queue, and displays the contents of a
selected message.
- Uses javax.swing for GUI components.
Files
-----
QBrowser.java Source file for this example.
*.class Prebuilt Java class files for this example.
README This file.
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer"s Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:/opt/sun/mq/share/lib/imq.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac QBrowser.java
Running the example
-------------------
By default QBrowser will connect to the broker running on localhost:7676.
You can use -DimqAddressList attribute to change the host, port and
transport:
java -DimqAddressList=mq://<host>:<port>/jms QBrowser
QBrowser will connect to the broker specified. The menu associated
with the "Queue Name" text field will populate with queue names
from the specified broker.
Select a queue from the menu, or type in a queue and click Browse.
QBrowser will list all messages in the queue.
Select a message and click "Details" to see the message contents
(properties, body, etc). Or double click.
If you don"t have any queues with messages on them, try running
the jms/SenderToQueue example to send a few messages to a queue.
For example:
[ Run from the jms demo subdirectory ]
java SenderToQueue myqueue 5
QBrowser updates it"s list of destinations every few minutes.
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* @(#)QBrowser.java 1.7 09/15/04
*
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved
* SUN PROPRIETARY/CONFIDENTIAL
* Use is subject to license terms.
*
*/
import java.awt.*;
import java.util.*;
import java.text.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.Destination;
import javax.jms.Queue;
import javax.jms.Topic;
import javax.jms.MessageConsumer;
import javax.jms.Message;
import javax.jms.QueueBrowser;
import javax.jms.DeliveryMode;
import javax.jms.StreamMessage;
import javax.jms.MapMessage;
import javax.jms.ObjectMessage;
import javax.jms.BytesMessage;
import javax.jms.TextMessage;
import javax.jms.JMSException;
/**
* The QBrowser example is a GUI application that lets you visually
* examine the contents of a JMS Queue. It is written using javax.swing.
*
* By default QBrowser will connect to the imqbrokerd running
* on localhost:7676. You can use -DimqAddressList attribute to change
* the host, port and transport:
*
* java -DimqAddressList=mq://<host>:<port>/jms QBrowser
*
* Once QBrowser is up, enter the name of a queue and click Browse.
* A list of messages on the queue will appear in the main window.
* Select a message and click "Details" to see the contents of the message.
*
* QBrowser consists of the following classes:
*
* QBrowser main(), the base GUI frame, and the JMS code
* MsgTable A TableModel for handling the display of messages on a queue
* PropertyPanel A JPanel with a scrolling text area for displaying
* simple text, or the contents of a HashMap.
* A number of minor event handling classes.
*
*/
public class QBrowser extends JPanel implements javax.jms.MessageListener {
JMenuItem exit_item = null;
JLabel qLabel = null;
JComboBox qBox = null;
JButton qBrowse = null;
JTable msgTable = null;
JLabel footerLabel = null;
JPanel footerPanel = null;
QueueBrowser qb = null;
Session session = null;
Connection connection = null;
Topic metricTopic = null;
MessageConsumer metricSubscriber = null;
JFrame detailsFrame = null;
PropertyPanel headerPanel = null, propertyPanel = null, bodyPanel = null;
static final String DEST_LIST_TOPIC_NAME = "mq.metrics.destination_list";
public static String version = "1.0";
public static String title = "QBrowser " + version;
public static String[] pad = {"", "0", "00", "000", "0000"};
public static String serverHost = "localhost";
public static int serverPort = 7676;
QBrowser() {
super(true);
setBorder(BorderFactory.createEtchedBorder());
setLayout(new BorderLayout());
// Create menu bar
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("File");
exit_item = new JMenuItem("Exit");
exit_item.addActionListener(new ExitListener());
menu.add(exit_item);
menubar.add(menu);
// Create panel to hold input area for Q name and Browse button
JPanel qPanel = new JPanel();
qPanel.setLayout(new BorderLayout());
qPanel.add(BorderLayout.NORTH, menubar);
qLabel = new JLabel("Queue Name: ");
qPanel.add(BorderLayout.WEST, qLabel);
qBox = new JComboBox();
Dimension d = qBox.getPreferredSize();
d.setSize(10 * d.getWidth(), d.getHeight());
qBox.setPreferredSize(d);
qBox.setEditable(true);
//qBox.addActionListener(new BrowseListener());
qPanel.add(BorderLayout.CENTER, qBox);
qBrowse = new JButton("Browse");
qBrowse.addActionListener(new BrowseListener() );
qPanel.add(BorderLayout.EAST, qBrowse);
qPanel.updateUI();
//qPanel.setBackground(Color.YELLOW);
add(BorderLayout.NORTH, qPanel);
// Create panel to hold table of messages
JPanel tPanel = new JPanel();
tPanel.setLayout(new BorderLayout());
msgTable = new JTable(new MsgTable());
msgTable.addMouseListener(new TableMouseListener());
TableColumn column = msgTable.getColumnModel().getColumn(1);
column.setPreferredWidth(190);
column = msgTable.getColumnModel().getColumn(2);
column.setPreferredWidth(130);
JScrollPane tablePane = new JScrollPane(msgTable);
tablePane.setPreferredSize(new Dimension(100, 300));
//tablePane.setMinimumSize(new Dimension(100, 100));
tPanel.add(BorderLayout.CENTER, tablePane);
add(BorderLayout.CENTER, tPanel);
// Create footer
footerPanel = new JPanel();
footerPanel.setLayout(new BorderLayout());
footerLabel = new JLabel("");
footerPanel.add(BorderLayout.WEST, footerLabel);
JButton details = new JButton("Details...");
details.addActionListener(new DetailsListener() );
footerPanel.add(BorderLayout.EAST, details);
add(BorderLayout.SOUTH, footerPanel);
setFooter("Enter a Queue Name and click Browse");
try {
connect();
} catch (JMSException ex) {
System.err.println("Could not initialize JMS: " + ex);
System.err.println(
"Are you sure there is an imqbrokerd running on " +
serverHost + ":" + serverPort + "?" );
usage();
}
}
private void shutdownJMS() {
try {
connection.close();
} catch (JMSException e) {
System.out.println("Exception closing JMS connection: " + e);
}
}
/**
* Initialize JMS by creating Connection and Session.
*/
private void initJMS() throws JMSException {
ConnectionFactory cf = null;
cf = new com.sun.messaging.ConnectionFactory();
connection = cf.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/**
* Setup a consumer that listens on the Message Queue monitoring topic
* that sends out lists of destinations.
*/
private void initDestListConsumer() throws JMSException {
metricTopic = session.createTopic(DEST_LIST_TOPIC_NAME);
metricSubscriber = session.createConsumer(metricTopic);
metricSubscriber.setMessageListener(this);
}
/**
* Set text on footer
*/
private void setFooter(String s) {
footerLabel.setText(s);
footerLabel.paintImmediately(footerLabel.getBounds());
}
/**
* Show the contents of a message in a seperate popup window
*/
private void showDetails(Message msg, int msgno) {
if (detailsFrame == null) {
// Create popup
detailsFrame = new JFrame();
detailsFrame.setTitle(QBrowser.title + " - Message Details");
detailsFrame.setBackground(Color.white);
detailsFrame.getContentPane().setLayout(new BorderLayout());
headerPanel = new PropertyPanel();
headerPanel.setTitle("JMS Headers");
detailsFrame.getContentPane().add(BorderLayout.NORTH, headerPanel);
propertyPanel = new PropertyPanel();
propertyPanel.setTitle("Message Properties");
detailsFrame.getContentPane().add(BorderLayout.CENTER, propertyPanel);
bodyPanel = new PropertyPanel();
bodyPanel.setTitle("Message body");
detailsFrame.getContentPane().add(BorderLayout.SOUTH, bodyPanel);
detailsFrame.pack();
}
// Load JMS headers from message
try {
HashMap hdrs = jmsHeadersToHashMap(msg);
headerPanel.setTitle("JMS Headers: Message #" + msgno);
headerPanel.load(hdrs);
} catch (JMSException ex) {
setFooter("Error: " + ex.getMessage());
}
// Load message properties
HashMap props = new HashMap();
// Get all message properties and stuff into a hash table
try {
for (Enumeration enu = msg.getPropertyNames();
enu.hasMoreElements();) {
String name = (enu.nextElement()).toString();
props.put(name, (msg.getObjectProperty(name)).toString());
}
} catch (JMSException ex) {
setFooter("Error: " + ex.getMessage());
}
propertyPanel.load(props);
// Load message body
bodyPanel.setTitle("Message Body: (" + QBrowser.messageType(msg) + ")");
bodyPanel.load(jmsMsgBodyAsString(msg));
detailsFrame.show();
}
private void connect() throws JMSException {
if (connection == null) {
setFooter("Connecting to " + serverHost + ":" +
serverPort + "...");
initJMS();
try {
initDestListConsumer();
} catch (JMSException e) {
// If we can"t subscribe to the mq.metrics topic then we
// are probably not running against an EE broker. That"s
// OK. It just means we can"t populate the Destination
// combo-box on the GUI.
//System.out.println("Could not subscribe to " +
// DEST_LIST_TOPIC_NAME);
}
connection.start();
setFooter("Connected to " + serverHost + ":" + serverPort);
}
}
/**
* Browse the queue
*/
private void doBrowse() {
ComboBoxEditor editor = qBox.getEditor();
String name = (String)editor.getItem();
setFooter("Browsing " + name + "...");
// Browse queue
try {
String selector = null;
Queue q = session.createQueue(name);
QueueBrowser qb;
if (selector == null) {
qb = session.createBrowser(q);
} else {
qb = session.createBrowser(q, selector);
}
// Load messages into table
MsgTable mt = (MsgTable)msgTable.getModel();
int n = mt.load(qb.getEnumeration());
setFooter(name + ": " + String.valueOf(n));
qb.close();
} catch (JMSException ex) {
setFooter(ex.getMessage());
}
}
/**
* Add a name to the "Queue Name" combo box menu
*/
private void addDestToMenu(String name) {
DefaultComboBoxModel model = (DefaultComboBoxModel)qBox.getModel();
if (model.getIndexOf(name) < 0) {
// Name is not in menu. Add it.
model.addElement(name);
}
}
/**
* Main
*/
public static void main (String args[]) {
if (args.length > 0) {
usage();
}
String address = System.getProperty("imqAddressList");
if (address != null) {
int i = address.indexOf("/");
int j = address.lastIndexOf(":");
int k = address.indexOf("/", j);
if (j > i+2) {
serverHost = address.substring(i+2, j);
}
if (k > j) {
serverPort = Integer.parseInt(address.substring(j+1, k));
}
}
JFrame frame = new JFrame();
frame.setTitle(QBrowser.title + " - " + serverHost + ":" + serverPort);
frame.setBackground(Color.white);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add("Center", new QBrowser());
frame.pack();
frame.show();
}
private static void usage() {
System.out.println(
"usage: java QBrowser \n" );
System.exit(1);
}
public static void dumpException(Exception e) {
Exception linked = null;
if (e instanceof JMSException) {
linked = ((JMSException)e).getLinkedException();
}
if (linked == null) {
e.printStackTrace();
} else {
System.err.println(e.toString());
linked.printStackTrace();
}
}
/**
* Return a string description of the type of JMS message
*/
static String messageType(Message m) {
if (m instanceof TextMessage) {
return "TextMessage";
} else if (m instanceof BytesMessage) {
return "BytesMessage";
} else if (m instanceof MapMessage) {
return "MapMessage";
} else if (m instanceof ObjectMessage) {
return "ObjectMessage";
} else if (m instanceof StreamMessage) {
return "StreamMessage";
} else if (m instanceof Message) {
return "Message";
} else {
// Unknown Message type
String type = m.getClass().getName();
StringTokenizer st = new StringTokenizer(type, ".");
String s = null;
while (st.hasMoreElements()) {
s = st.nextToken();
}
return s;
}
}
/**
* Return a string representation of the body of a JMS
* bytes message. This is basically a hex dump of the body.
* Note, this only looks at the first 1K of the message body.
*/
private static String jmsBytesBodyAsString(Message m) {
byte[] body = new byte[1024];
int n = 0;
if (m instanceof BytesMessage) {
try {
((BytesMessage)m).reset();
n = ((BytesMessage)m).readBytes(body);
} catch (JMSException ex) {
return (ex.toString());
}
} else if (m instanceof StreamMessage) {
try {
((StreamMessage)m).reset();
n = ((StreamMessage)m).readBytes(body);
} catch (JMSException ex) {
return (ex.toString());
}
}
if (n <= 0) {
return "<empty body>";
} else {
return(toHexDump(body, n) +
((n >= body.length ) ? "\n. . ." : "") );
}
}
/**
* Return a string representation of a JMS message body
*/
private static String jmsMsgBodyAsString(Message m) {
if (m instanceof TextMessage) {
try {
return ((TextMessage) m).getText();
} catch (JMSException ex) {
return ex.toString();
}
} else if (m instanceof BytesMessage) {
return jmsBytesBodyAsString(m);
} else if (m instanceof MapMessage) {
MapMessage msg = (MapMessage)m;
HashMap props = new HashMap();
// Get all MapMessage properties and stuff into a hash table
try {
for (Enumeration enu = msg.getMapNames();
enu.hasMoreElements();) {
String name = (enu.nextElement()).toString();
props.put(name, (msg.getObject(name)).toString());
}
return props.toString();
} catch (JMSException ex) {
return (ex.toString());
}
} else if (m instanceof ObjectMessage) {
ObjectMessage msg = (ObjectMessage)m;
Object obj = null;
try {
obj = msg.getObject();
if (obj != null) {
return obj.toString();
} else {
return "null";
}
} catch (Exception ex) {
return (ex.toString());
}
} else if (m instanceof StreamMessage) {
return jmsBytesBodyAsString(m);
} else if (m instanceof Message) {
return "Can"t get body for message of type Message";
}
return "Unknown message type " + m;
}
/**
* Takes the JMS header fields of a JMS message and puts them in
* a HashMap
*/
private static HashMap jmsHeadersToHashMap(Message m) throws JMSException {
HashMap hdrs = new HashMap();
String s = null;
s = m.getJMSCorrelationID();
hdrs.put("JMSCorrelationID", s);
s = String.valueOf(m.getJMSDeliveryMode());
hdrs.put("JMSDeliverMode", s);
Destination d = m.getJMSDestination();
if (d != null) {
if (d instanceof Queue) {
s = ((Queue)d).getQueueName();
} else {
s = ((Topic)d).getTopicName();
}
} else {
s = "";
}
hdrs.put("JMSDestination", s);
s = String.valueOf(m.getJMSExpiration());
hdrs.put("JMSExpiration", s);
s = m.getJMSMessageID();
hdrs.put("JMSMessageID", s);
s = String.valueOf(m.getJMSPriority());
hdrs.put("JMSPriority", s);
s = String.valueOf(m.getJMSRedelivered());
hdrs.put("JMSRedelivered", s);
d = m.getJMSDestination();
if (d != null) {
if (d instanceof Queue) {
s = ((Queue)d).getQueueName();
} else {
s = ((Topic)d).getTopicName();
}
} else {
s = "";
}
hdrs.put("JMSReplyTo", s);
s = String.valueOf(m.getJMSTimestamp());
hdrs.put("JMSTimestamp", s);
s = m.getJMSType();
hdrs.put("JMSType", s);
return hdrs;
}
/**
* Takes a buffer of bytes and returns a hex dump. Each hex digit
* represents 4 bits. The hex digits are formatted into groups of
* 4 (2 bytes, 16 bits). Each line has 8 groups, so each line represents
* 128 bits.
*/
private static String toHexDump(byte[] buf, int length) {
// Buffer must be an even length
if (buf.length % 2 != 0) {
throw new IllegalArgumentException();
}
int value;
StringBuffer sb = new StringBuffer(buf.length * 2);
/* Assume buf is in network byte order (most significant byte
* is buf[0]). Convert two byte pairs to a short, then
* display as a hex string.
*/
int n = 0;
while (n < buf.length && n < length) {
value = buf[n + 1] & 0xFF; // Lower byte
value |= (buf[n] << 8) & 0xFF00; // Upper byte
String s = Integer.toHexString(value);
// Left bad with 0"s
sb.append(pad[4 - s.length()]);
sb.append(s);
n += 2;
if (n % 16 == 0) {
sb.append("\n");
} else {
sb.append(" ");
}
}
return sb.toString();
}
/**
* Consumer that listens on the MQ monitoring topic that sends
* out lists of destination names. We use this to update the
* combo-box menu.
*/
public void onMessage(Message msg) {
try {
MapMessage mapMsg = (MapMessage)msg;
String type = mapMsg.getStringProperty("type");
if (type.equals(DEST_LIST_TOPIC_NAME)) {
String oneRow[] = new String[ 3 ];
TreeSet names = new TreeSet();
/*
* Extract list of destinations
*/
for (Enumeration e = mapMsg.getMapNames();
e.hasMoreElements();) {
String name = (String)e.nextElement();
Hashtable values = (Hashtable)mapMsg.getObject(name);
// Sort names by putting them into TreeSet
if (values.get("type").toString().equals("queue")) {
names.add((String)values.get("name"));
}
}
// Add sorted names to combo box menu
for (Iterator iter = names.iterator(); iter.hasNext();) {
addDestToMenu((String)iter.next());
}
} else {
System.err.println(
"Msg received: not destination list metric type");
}
} catch (Exception e) {
System.err.println("onMessage: Exception caught: " + e);
}
}
class OptionListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
System.out.println("ItemEvent");
}
}
class ExitListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
shutdownJMS();
System.exit(0);
}
}
class BrowseListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
doBrowse();
}
}
class TableMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int row = msgTable.getSelectedRow();
MsgTable mt = (MsgTable)msgTable.getModel();
Message msg = mt.getMessageAtRow(row);
showDetails(msg, row);
}
}
}
class DetailsListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
int row = msgTable.getSelectedRow();
if (row < 0) {
setFooter("Please select a message");
return;
}
MsgTable mt = (MsgTable)msgTable.getModel();
Message msg = mt.getMessageAtRow(row);
showDetails(msg, row);
}
}
/**
* A table of JMS Messages
*/
class MsgTable extends AbstractTableModel {
final String[] columnNames =
{"#", "Timestamp", "Type", "Mode", "Priority"};
SimpleDateFormat df =
new SimpleDateFormat("dd/MMM/yyyy:kk:mm:ss z");
LinkedList list = null;
public int getRowCount() {
if (list == null) {
return 0;
} else {
return list.size();
}
}
public int getColumnCount() {
return columnNames.length;
}
public String getColumnName(int column) {
return columnNames[column];
}
public Object getValueAt(int row, int column) {
if (list == null) {
return null;
}
Message m = (Message)list.get(row);
if (m == null) {
return "null";
}
try {
switch (column) {
case 0:
// Message number is the same as the row number
return new Integer(row);
case 1:
// Need to format into date/time
return df.format(new Date(m.getJMSTimestamp()));
case 2:
return QBrowser.messageType(m);
case 3:
// Delivery mode
int mode = m.getJMSDeliveryMode();
if (mode == DeliveryMode.PERSISTENT) {
return "P";
} else if (mode == DeliveryMode.NON_PERSISTENT) {
return "NP";
} else {
return String.valueOf(mode) + "?";
}
case 4:
// Priority
return new Integer(m.getJMSPriority());
default:
return "Bad column value: " + column;
}
} catch (JMSException e) {
return ("Error: " + e);
}
}
/**
* Load and enumeration of messages into the table
*/
int load (Enumeration e) {
if (e == null) {
return 0;
}
list = new LinkedList();
while (e.hasMoreElements()) {
list.add(e.nextElement());
}
fireTableDataChanged();
return list.size();
}
Message getMessageAtRow(int row) {
if (list == null) return null;
return((Message)list.get(row));
}
}
/**
* A panel with a text area that knows how to format and display
* a HashMap of values.
*/
class PropertyPanel extends JPanel {
JLabel label = null;
JTextArea textArea = null;
JScrollPane areaScrollPane = null;
PropertyPanel() {
super(true);
setBorder(BorderFactory.createEtchedBorder());
setLayout(new BorderLayout());
label = new JLabel();
textArea = new JTextArea();
textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
areaScrollPane = new JScrollPane(textArea);
areaScrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(500, 150));
add(BorderLayout.NORTH, label);
add(BorderLayout.CENTER, areaScrollPane);
}
void setTitle(String title) {
label.setText(title);
}
/**
* Display a HashMap in the text window
*/
void load(HashMap map) {
StringBuffer buf = new StringBuffer();
Set entries = map.entrySet();
Map.Entry entry = null;
Iterator iter = entries.iterator();
while (iter.hasNext()) {
entry = (Map.Entry)iter.next();
String key = entry.getKey().toString();
Object o = entry.getValue();
String value = "";
if (o != null) {
value = o.toString();
}
buf.append(pad(key + ": ", 20));
buf.append(value + "\n");
}
textArea.setText(buf.toString());
areaScrollPane.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
}
/**
* Display text in the text window
*/
void load(String s) {
textArea.setText(s);
}
/**
* Pad a string to the specified width, right justified.
* If the string is longer than the width you get back the
* original string.
*/
String pad(String s, int width) {
// Very inefficient, but we don"t care
StringBuffer sb = new StringBuffer();
int padding = width - s.length();
if (padding <= 0) {
return s;
}
while (padding > 0) {
sb.append(" ");
padding--;
}
sb.append(s);
return sb.toString();
}
}
}
MQ Cluster Monitor
/*
* @(#)MQClusterMonitor.java 1.7 05/09/19
*
* Copyright (c) 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.util.HashMap;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.management.*;
import javax.management.remote.*;
import javax.management.openmbean.rupositeData;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.AdminConnectionConfiguration;
import com.sun.messaging.jms.management.server.*;
public class MQClusterMonitor implements ActionListener,
Runnable {
JFrame f;
MQConnectDialog connectDialog = null;
JMenuItem exit, connect, disconnect;
JTextArea logMsgArea, statusTextArea;
JLabel brokerAddress;
JTable clsTable;
String address = null, adminUser = "admin", adminPasswd = "admin";
boolean stopRequested = false;
long seconds = 2;
AdminConnectionFactory acf;
JMXConnector jmxc;
MBeanServerConnection mbsc;
ObjectName clsMon = null;
NotificationFilterSupport myFilter = null;
public MQClusterMonitor(JFrame f, String address,
String adminUser, String adminPasswd,
long seconds) {
this.f = f;
this.address = address;
this.adminUser = adminUser;
this.adminPasswd = adminPasswd;
this.seconds = seconds;
try {
clsMon = new ObjectName(MQObjectName.CLUSTER_MONITOR_MBEAN_NAME);
} catch (Exception e) {
addStatusText("Caught exception while creating Log MBean ObjectName: " + e);
}
initGUI();
if ((address != null) && (adminUser != null) && (adminPasswd != null)) {
doConnect();
}
}
public synchronized void requestStop() {
stopRequested = true;
ClusterTableModel m = (ClusterTableModel)clsTable.getModel();
m.load(null);
}
public synchronized void resetStop() {
stopRequested = false;
}
public synchronized boolean stopRequested() {
return (stopRequested);
}
public void run() {
addStatusText("Monitor thread started (refresh interval = "
+ seconds
+ " seconds).");
while (true) {
try {
Thread.sleep(seconds * 1000);
if (stopRequested()) {
addStatusText("Monitor thread stopped");
break;
}
} catch (java.lang.InterruptedException ie) {
addStatusText("Exception caught while waiting to reload: " + ie);
}
load();
}
}
public void load() {
try {
CompositeData cd[] = (CompositeData[])mbsc.invoke(clsMon,
ClusterOperations.GET_BROKER_INFO,
null, null);
ClusterTableModel m = (ClusterTableModel)clsTable.getModel();
m.load(cd);
} catch (Exception e) {
addStatusText("Exception caught while reloading data: " + e);
e.printStackTrace();
}
}
private void initGUI() {
JMenuBar menubar = createMenubar();
JComponent toolbar = createToolBar();
JPanel mainPanel = createMainPanel();
JPanel statusArea = createStatusArea();
f.setJMenuBar(menubar);
f.getContentPane().add(toolbar, BorderLayout.NORTH);
f.getContentPane().add(mainPanel, BorderLayout.CENTER);
f.getContentPane().add(statusArea, BorderLayout.SOUTH);
}
public void addStatusText(String statusText) {
statusTextArea.append(statusText);
statusTextArea.setCaretPosition(statusTextArea.getText().length());
statusTextArea.append("\n");
}
public void clearStatus() {
statusTextArea.setText("");
}
public void doConnect() {
try {
acf = new AdminConnectionFactory();
if (address != null) {
acf.setProperty(AdminConnectionConfiguration.imqAddress,
address);
}
jmxc = acf.createConnection(adminUser, adminPasswd);
mbsc = jmxc.getMBeanServerConnection();
addStatusText("Connected to broker at: "
+ acf.getProperty(AdminConnectionConfiguration.imqAddress));
brokerAddress.setText(
acf.getProperty(AdminConnectionConfiguration.imqAddress));
resetStop();
new Thread(this).start();
connect.setEnabled(false);
disconnect.setEnabled(true);
} catch (Exception e) {
addStatusText("Caught exception while connecting: " + e);
}
}
public void doDisconnect() {
try {
requestStop();
addStatusText("Disconnecting from broker at: "
+ acf.getProperty(AdminConnectionConfiguration.imqAddress));
brokerAddress.setText("<none>");
if (jmxc != null) {
jmxc.close();
}
jmxc = null;
mbsc = null;
acf = null;
connect.setEnabled(true);
disconnect.setEnabled(false);
} catch (Exception e) {
addStatusText("Caught exception while disconnecting: " + e);
}
}
private JMenuBar createMenubar() {
JMenuBar menubar;
JMenu menu, logLevelMenu;
menubar = new JMenuBar();
menu = new JMenu("ClusterMonitor");
menubar.add(menu);
connect = new JMenuItem("Connect");
connect.addActionListener(this);
menu.add(connect);
disconnect = new JMenuItem("Disconnect");
disconnect.addActionListener(this);
disconnect.setEnabled(false);
menu.add(disconnect);
menu.addSeparator();
exit = new JMenuItem("Exit");
exit.addActionListener(this);
menu.add(exit);
return (menubar);
}
private JPanel createMainPanel() {
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
clsTable = new JTable(new ClusterTableModel()) {
public TableCellRenderer getCellRenderer(int row, int col) {
DefaultTableCellRenderer rowRenderer;
if (col != 2) {
return (super.getCellRenderer(row, col));
}
int state = getBrokerState(row);
switch (state) {
case BrokerState.TAKEOVER_COMPLETE:
rowRenderer = new DefaultTableCellRenderer();
rowRenderer.setBackground(Color.yellow);
return (rowRenderer);
case BrokerState.BROKER_DOWN:
case BrokerState.TAKEOVER_STARTED:
case BrokerState.SHUTDOWN_STARTED:
rowRenderer = new DefaultTableCellRenderer();
rowRenderer.setBackground(Color.red);
return (rowRenderer);
/*
* default case handles:
* BrokerState.OPERATING:
* BrokerState.QUIESCE_STARTED:
* BrokerState.QUIESCE_COMPLETE:
*/
default:
return (super.getCellRenderer(row, col));
}
}
public int getBrokerState(int row) {
ClusterTableModel m = (ClusterTableModel)clsTable.getModel();
return (m.getBrokerState(row));
}
};
JScrollPane tablePane = new JScrollPane(clsTable);
tablePane.setPreferredSize(new Dimension(640, 100));
p.add(BorderLayout.CENTER, tablePane);
return (p);
}
private JComponent createToolBar() {
JPanel p = new JPanel();
JLabel l;
p.setLayout(new FlowLayout(FlowLayout.LEFT));
l = new JLabel("Cluster state as reported by broker at address: ");
p.add(l);
brokerAddress = new JLabel("<none>");
p.add(brokerAddress);
return (p);
}
private JPanel createStatusArea() {
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
statusTextArea = new JTextArea(5, 60);
statusTextArea.setLineWrap(true);
statusTextArea.setEditable(false);
JScrollPane statusTextPane = new JScrollPane(statusTextArea);
p.add(statusTextPane, BorderLayout.CENTER);
return (p);
}
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if (src instanceof JMenuItem) {
JMenuItem mi = (JMenuItem)src;
if (src == exit) {
System.exit(0);
} else if (src == connect) {
showConnectDialog();
} else if (src == disconnect) {
doDisconnect();
}
} else if (src instanceof JButton) {
address = connectDialog.getAddress();
adminUser = connectDialog.getUserName();
adminPasswd = connectDialog.getPassword();
doConnect();
}
}
private void showConnectDialog() {
if (connectDialog == null) {
connectDialog = new MQConnectDialog(f, "Connect to Broker", this);
connectDialog.setAddress((address == null) ?
getDefaultAddress() : address);
connectDialog.setUserName((adminUser == null) ?
getDefaultUserName() : adminUser);
connectDialog.setPassword((adminPasswd == null) ?
getDefaultPassword() : adminPasswd);
}
connectDialog.setLocationRelativeTo(f);
connectDialog.setVisible(true);
}
private static void doExit() {
System.exit(0);
}
private String getDefaultUserName() {
AdminConnectionFactory acf = new AdminConnectionFactory();
String addr;
try {
addr = acf.getProperty(AdminConnectionConfiguration.imqDefaultAdminUsername);
} catch(Exception e) {
addr = null;
}
return (addr);
}
private String getDefaultPassword() {
AdminConnectionFactory acf = new AdminConnectionFactory();
String addr;
try {
addr = acf.getProperty(AdminConnectionConfiguration.imqDefaultAdminPassword);
} catch(Exception e) {
addr = null;
}
return (addr);
}
private String getDefaultAddress() {
/*
AdminConnectionFactory acf = new AdminConnectionFactory();
String addr;
try {
addr = acf.getProperty(AdminConnectionConfiguration.imqAddress);
} catch(Exception e) {
addr = null;
}
return (addr);
*/
return ("localhost:7676");
}
public static void main(String[] args) {
JFrame frame;
MQClusterMonitor s;
String address = null, adminUser = null, adminPasswd = null,
secondStr = null;
long seconds = 2;
for (int i = 0; i < args.length; ++i) {
if (args[i].equals("-b")) {
if (++i >= args.length) {
usage();
}
address = args[i];
} else if (args[i].equals("-u")) {
if (++i >= args.length) {
usage();
}
adminUser = args[i];
} else if (args[i].equals("-p")) {
if (++i >= args.length) {
usage();
}
adminPasswd = args[i];
} else if (args[i].equals("-int")) {
if (++i >= args.length) {
usage();
}
secondStr = args[i];
try {
seconds = Long.valueOf(secondStr).longValue();
} catch(NumberFormatException nfe) {
usage("Failed to parse interval value: " + secondStr);
}
} else {
usage();
}
}
frame = new JFrame("MQ Cluster Monitor");
s = new MQClusterMonitor(frame, address, adminUser, adminPasswd, seconds);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
doExit();
}
});
frame.pack();
frame.setVisible(true);
}
public static void usage() {
usage(null);
}
public static void usage(String msg) {
if (msg != null) {
System.err.println(msg);
}
System.err.println("java MQClusterMonitor"
+ "[-b <host:port>] [-u <admin user name>] [-p <admin password>]");
doExit();
}
}
class ClusterTableModel extends AbstractTableModel {
private String[] columnNames = {"Broker ID",
"Broker Address",
"Broker State",
"# Msgs in Store",
"Takeover Broker ID",
"Time since last status timestamp"};
CompositeData clusterInfo[];
public ClusterTableModel() {
}
public void load(CompositeData cd[]) {
if (cd != null) {
clusterInfo = cd;
} else {
clusterInfo = null;
}
fireTableDataChanged();
}
public int getRowCount() {
if (clusterInfo == null) {
return (0);
}
return (clusterInfo.length);
}
public int getColumnCount() {
return (columnNames.length);
}
public String getColumnName(int column) {
return columnNames[column];
}
public Object getValueAt(int row, int column) {
if ((clusterInfo == null) || (clusterInfo.length == 0)) {
return ("");
}
CompositeData info = clusterInfo[row];
switch (column) {
case 0:
return (info.get(BrokerClusterInfo.ID));
case 1:
return (info.get(BrokerClusterInfo.ADDRESS));
case 2:
return (BrokerState.toString(((Integer)
info.get(BrokerClusterInfo.STATE)).intValue()));
case 3:
return ((info.get(BrokerClusterInfo.NUM_MSGS)).toString());
case 4:
return (info.get(BrokerClusterInfo.TAKEOVER_BROKER_ID));
case 5:
long tmpLong = ((Long)info.get(BrokerClusterInfo.STATUS_TIMESTAMP)).longValue();
long idle = System.currentTimeMillis() - tmpLong;
return (getTimeString(idle));
}
return ("");
}
public int getBrokerState(int row) {
if ((clusterInfo == null) || (clusterInfo.length == 0)) {
return (BrokerState.BROKER_DOWN);
}
CompositeData info = clusterInfo[row];
if (info == null) {
return (BrokerState.BROKER_DOWN);
}
int state = ((Integer)info.get(BrokerClusterInfo.STATE)).intValue();
return (state);
}
private String getTimeString(long millis) {
String ret = null;
if (millis < 1000) {
ret = millis + " milliseconds";
} else if (millis < (60 * 1000)) {
long seconds = millis / 1000;
ret = seconds + " seconds";
} else if (millis < (60 * 60 * 1000)) {
long mins = millis / (60 * 1000);
ret = mins + " minutes";
} else {
ret = "> 1 hour";
}
return (ret);
}
}
/*
* @(#)MQConnectDialog.java 1.1 05/06/06
*
* Copyright (c) 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MQConnectDialog extends JDialog
implements ActionListener {
JButton apply, cancel;
JTextField address, username;
JPasswordField password;
private boolean applyHit = false;
private ActionListener applyListener = null;
public MQConnectDialog(Frame parent, String title,
ActionListener applyListener) {
super(parent, title, true);
this.applyListener = applyListener;
initContentPane();
pack();
}
public boolean applyDone() {
return (applyHit);
}
private void initContentPane() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
/*
* Create "work" panel
*/
JPanel workPanel = createWorkPanel();
/*
* Create button panel
*/
JPanel buttonPanel = createButtonPanel();
panel.add(workPanel, "Center");
panel.add(buttonPanel, "South");
getContentPane().add(panel);
}
private JPanel createWorkPanel() {
JPanel workPanel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
JLabel l;
workPanel.setLayout(gridbag);
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.NONE;
c.insets = new Insets(2, 2, 2, 2);
c.ipadx = 0;
c.ipady = 0;
c.weightx = 1.0;
c.gridx = 0;
c.gridy = 0;
l = new JLabel("Address:");
gridbag.setConstraints(l,c);
workPanel.add(l);
c.gridx = 1;
c.gridy = 0;
address = new JTextField(20);
gridbag.setConstraints(address,c);
workPanel.add(address);
c.gridx = 0;
c.gridy = 1;
l = new JLabel("Name:");
gridbag.setConstraints(l,c);
workPanel.add(l);
c.gridx = 1;
c.gridy = 1;
username = new JTextField(20);
gridbag.setConstraints(username, c);
workPanel.add(username);
c.gridx = 0;
c.gridy = 2;
l = new JLabel("Password:");
gridbag.setConstraints(l,c);
workPanel.add(l);
c.gridx = 1;
c.gridy = 2;
password = new JPasswordField(20);
gridbag.setConstraints(password, c);
workPanel.add(password);
return (workPanel);
}
public void setAddress(String s) {
address.setText(s);
}
public String getAddress() {
return (address.getText());
}
public void setUserName(String s) {
username.setText(s);
}
public String getUserName() {
return (username.getText());
}
public void setPassword(String s) {
password.setText(s);
}
public String getPassword() {
return (new String(password.getPassword()));
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
apply = new JButton("Apply");
apply.addActionListener(this);
if (applyListener != null) {
apply.addActionListener(applyListener);
}
buttonPanel.add(apply);
cancel = new JButton("Cancel");
cancel.addActionListener(this);
buttonPanel.add(cancel);
return (buttonPanel);
}
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if (src == apply) {
applyHit = true;
setVisible(false);
} else if (src == cancel) {
applyHit = false;
setVisible(false);
}
}
}
Reads a textfile, creates a BytesMessage from it, then reads the message
/*
* @(#)BytesMessages.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.io.*;
import javax.jms.*;
/**
* The BytesMessages class consists only of a main method, which reads a
* textfile, creates a BytesMessage from it, then reads the message. It does
* not send the message.
* <p>
* Specify an existing text file name on the command line when you run
* the program.
* <p>
* This is not a realistic example of the use of the BytesMessage message type,
* which is intended for client encoding of existing message formats. (If
* possible, one of the other message types, such as StreamMessage or
* MapMessage, should be used instead.) However, it shows how to use a buffer
* to write or read a BytesMessage when you do not know its length.
*
* @author Kim Haase
* @version 1.5, 08/09/00
*/
public class BytesMessages {
/**
* Main method.
*
* @param args the name of the text file used by the example
*/
public static void main(String[] args) {
String filename = null;
FileInputStream inStream = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
BytesMessage bytesMessage = null;
int bytes_read = 0;
final int BUFLEN = 64;
byte[] buf1 = new byte[BUFLEN];
byte[] buf2 = new byte[BUFLEN];
int length = 0;
int exitResult = 0;
/*
* Read text file name from command line and create input stream.
*/
if (args.length != 1) {
System.out.println("Usage: java BytesMessages <filename>");
System.exit(1);
}
try {
filename = new String(args[0]);
inStream = new FileInputStream(filename);
} catch (IOException e) {
System.out.println("Problem getting file: " + e.toString());
System.exit(1);
}
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
try {
/*
* Create a BytesMessage.
* Read a byte stream from the input stream into a buffer and
* construct a BytesMessage, using the three-argument form
* of the writeBytes method to ensure that the message contains
* only the bytes read from the file, not any leftover characters
* in the buffer.
*/
bytesMessage = session.createBytesMessage();
while ((bytes_read = inStream.read(buf1)) != -1) {
bytesMessage.writeBytes(buf1, 0, bytes_read);
System.out.println("Writing " + bytes_read
+ " bytes into message");
}
/*
* Reset the message to the beginning, then use readBytes to
* extract its contents into another buffer, casting the byte array
* elements to char so that they will display intelligibly.
*/
bytesMessage.reset();
do {
length = bytesMessage.readBytes(buf2);
if (length != -1) {
System.out.println("Reading " + length
+ " bytes from message: ");
for (int i = 0; i < length; i++) {
System.out.print((char)buf2[i]);
}
}
System.out.println();
} while (length >= BUFLEN);
} catch (JMSException e) {
System.out.println("JMS exception occurred: " + e.toString());
exitResult = 1;
} catch (IOException e) {
System.out.println("I/O exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
SampleUtilities.exit(exitResult);
}
}
Sends several messages to a queue
/*
* @(#)SenderToQueue.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The SenderToQueue class consists only of a main method, which sends
* several messages to a queue.
* <p>
* Run this program in conjunction with either SynchQueueExample or
* AsynchQueueExample. Specify a queue name on the command line when you run
* the program. By default, the program sends one message. Specify a number
* after the queue name to send that number of messages.
*
* @author Kim Haase
* @version 1.2, 08/18/00
*/
public class SenderToQueue {
/**
* Main method.
*
* @param args the queue used by the example and, optionally, the
* number of messages to send
*/
public static void main(String[] args) {
String queueName = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Queue queue = null;
MessageProducer msgProducer = null;
TextMessage message = null;
final int NUM_MSGS;
final String MSG_TEXT = new String("Here is a message");
int exitResult = 0;
if ( (args.length < 1) || (args.length > 2) ) {
System.out.println("Usage: java SenderToQueue <queue_name> [<number_of_messages>]");
System.exit(1);
}
queueName = new String(args[0]);
System.out.println("Queue name is " + queueName);
if (args.length == 2){
NUM_MSGS = (new Integer(args[1])).intValue();
} else {
NUM_MSGS = 1;
}
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = SampleUtilities.getQueue(queueName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create producer.
* Create text message.
* Send five messages, varying text slightly.
* Send end-of-messages message.
* Finally, close connection.
*/
try {
msgProducer = session.createProducer(queue);
message = session.createTextMessage();
for (int i = 0; i < NUM_MSGS; i++) {
message.setText(MSG_TEXT + " " + (i + 1));
System.out.println("Sending message: " + message.getText());
msgProducer.send(message);
}
// Send a non-text control message indicating end of messages.
msgProducer.send(session.createMessage());
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
SampleUtilities.exit(exitResult);
}
}
The BrokerMetrics example is a JMS application that monitors the Sun Java(tm) System Message Queue broker
/*
* @(#)BrokerMetrics.java 1.3 04/01/05
*
* Copyright (c) 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.util.Enumeration;
import java.util.Properties;
import javax.jms.*;
/**
* The BrokerMetrics example is a JMS application that monitors the
* Sun Java(tm) System Message Queue broker. It does so by subscribing to a
* topic named "mq.metrics.broker". The messages that arrive contain
* Broker metric information such as number of messages flowing in/out
* of the broker, size in bytes of messages flowing in/out etc.
*
* This application also shows how to use the timestamp in each metric
* message to calculate rates e.g. rate at which messages are flowing
* into the broker.
*
* This application takes the following arguments:
* -m ttl Show totals e.g. total/accumulative number of msgs
* that flowed in/out of the broker. This is the
* default.
* -m rts Show rates e.g. rate of mesasge flow in/out of
* broker.
*
* By default BrokerMetrics will connect to the broker running on localhost:7676.
* You can use -DimqAddressList attribute to change the host, port and
* transport:
*
* java -DimqAddressList=mq://<host>:<port>/jms DestListMetrics
*
*/
public class BrokerMetrics implements MessageListener {
ConnectionFactory metricConnectionFactory;
Connection metricConnection;
Session metricSession;
MessageConsumer metricConsumer;
Topic metricTopic;
MetricsPrinter mp;
int rowsPrinted = 0;
boolean showTotals = true;
MapMessage previous = null;
public static void main(String args[]) {
boolean totals = true;
for (int i = 0; i < args.length; ++i) {
if (args[i].equals("-m")) {
String type = args[i+1];
if (type.equals("ttl")) {
totals = true;
} else if (type.equals("rts")) {
totals = false;
}
}
}
BrokerMetrics bm = new BrokerMetrics();
bm.showTotals = totals;
bm.initPrinter();
bm.initJMS();
bm.subscribeToMetric();
}
/*
* Initializes the class that does the printing, MetricsPrinter.
* See the MetricsPrinter class for details.
*/
private void initPrinter() {
String oneRow[] = new String[ 8 ];
int span[] = new int[ 8 ];
int i = 0;
mp = new MetricsPrinter(8, 2, "-", MetricsPrinter.CENTER);
mp.setTitleAlign(MetricsPrinter.CENTER);
span[i++] = 2;
span[i++] = 0;
span[i++] = 2;
span[i++] = 0;
span[i++] = 2;
span[i++] = 0;
span[i++] = 2;
span[i++] = 0;
i = 0;
if (showTotals) {
oneRow[i++] = "Msgs";
oneRow[i++] = "";
oneRow[i++] = "Msg Bytes";
oneRow[i++] = "";
oneRow[i++] = "Pkts";
oneRow[i++] = "";
oneRow[i++] = "Pkt Bytes";
oneRow[i++] = "";
} else {
oneRow[i++] = "Msgs/sec";
oneRow[i++] = "";
oneRow[i++] = "Msg Bytes/sec";
oneRow[i++] = "";
oneRow[i++] = "Pkts/sec";
oneRow[i++] = "";
oneRow[i++] = "Pkt Bytes/sec";
oneRow[i++] = "";
}
mp.addTitle(oneRow, span);
i = 0;
oneRow[i++] = "In";
oneRow[i++] = "Out";
oneRow[i++] = "In";
oneRow[i++] = "Out";
oneRow[i++] = "In";
oneRow[i++] = "Out";
oneRow[i++] = "In";
oneRow[i++] = "Out";
mp.addTitle(oneRow);
}
/**
* Create the Connection and Session etc.
*/
public void initJMS() {
try {
metricConnectionFactory = new com.sun.messaging.ConnectionFactory();
metricConnection = metricConnectionFactory.createConnection();
metricConnection.start();
// creating Session
// Transaction Mode: None
// Acknowledge Mode: Automatic
metricSession = metricConnection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch(Exception e) {
System.err.println("Cannot create metric connection or session: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
public void subscribeToMetric() {
try {
metricTopic = metricSession.createTopic("mq.metrics.broker");
metricConsumer = metricSession.createConsumer(metricTopic);
metricConsumer.setMessageListener(this);
} catch(JMSException e) {
System.err.println("Cannot subscribe to metric topic: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
/*
* When a metric message arrives
* - verify it"s type
* - extract it"s fields
* - print one row of output
*/
public void onMessage(Message m) {
try {
MapMessage mapMsg = (MapMessage)m;
String type = mapMsg.getStringProperty("type");
if (type.equals("mq.metrics.broker")) {
if (showTotals) {
doTotals(mapMsg);
} else {
doRates(mapMsg);
}
} else {
System.err.println("Msg received: not broker metric type");
}
} catch (Exception e) {
System.err.println("onMessage: Exception caught: " + e);
}
}
private void doTotals(MapMessage mapMsg) {
try {
String oneRow[] = new String[ 8 ];
int i = 0;
/*
* Extract broker metrics
*/
oneRow[i++] = Long.toString(mapMsg.getLong("numMsgsIn"));
oneRow[i++] = Long.toString(mapMsg.getLong("numMsgsOut"));
oneRow[i++] = Long.toString(mapMsg.getLong("msgBytesIn"));
oneRow[i++] = Long.toString(mapMsg.getLong("msgBytesOut"));
oneRow[i++] = Long.toString(mapMsg.getLong("numPktsIn"));
oneRow[i++] = Long.toString(mapMsg.getLong("numPktsOut"));
oneRow[i++] = Long.toString(mapMsg.getLong("pktBytesIn"));
oneRow[i++] = Long.toString(mapMsg.getLong("pktBytesOut"));
mp.add(oneRow);
if ((rowsPrinted % 20) == 0) {
mp.print();
} else {
mp.print(false);
}
rowsPrinted++;
mp.clear();
} catch (Exception e) {
System.err.println("onMessage: Exception caught: " + e);
}
}
private void doRates(MapMessage mapMsg) {
String oneRow[] = new String[ 8 ];
int i = 0;
try {
if (previous == null) {
oneRow[i++] = "0";
oneRow[i++] = "0";
oneRow[i++] = "0";
oneRow[i++] = "0";
oneRow[i++] = "0";
oneRow[i++] = "0";
oneRow[i++] = "0";
oneRow[i++] = "0";
} else {
long prevVal, newVal, prevSecs, newSecs, tmp;
float secs;
prevSecs = previous.getLongProperty("timestamp");
newSecs = mapMsg.getLongProperty("timestamp");
secs = (float)(newSecs - prevSecs)/(float)1000;
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numMsgsIn"));
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numMsgsOut"));
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "msgBytesIn"));
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "msgBytesOut"));
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numPktsIn"));
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numPktsOut"));
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "pktBytesIn"));
oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "pktBytesOut"));
}
previous = mapMsg;
mp.add(oneRow);
if ((rowsPrinted % 20) == 0) {
mp.print();
} else {
mp.print(false);
}
rowsPrinted++;
mp.clear();
} catch (Exception e) {
System.err.println("onMessage: Exception caught: " + e);
e.printStackTrace();
}
}
private long getRate(MapMessage previous, MapMessage mapMsg, float secs,
String propName) throws JMSException {
long prevVal, newVal, prevSecs, newSecs, tmp;
prevVal = previous.getLong(propName);
newVal = mapMsg.getLong(propName);
tmp = (long)((newVal - prevVal)/secs);
return (tmp);
}
}
The DestListMetrics example is a JMS application that monitors the destinations on a Sun Java(tm) System Message Queue broker
/*
* @(#)DestListMetrics.java 1.3 04/01/05
*
* Copyright (c) 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.util.Enumeration;
import java.util.Properties;
import java.util.Hashtable;
import javax.jms.*;
/**
* The DestListMetrics example is a JMS application that monitors the
* destinations on a Sun Java(tm) System Message Queue broker. It does so by
* subscribing to a topic named "mq.metrics.destination_list". The
* messages that arrive contain information describing the
* destinations that currently exist on the broker such as:
* - destination name
* - destination type
* - whether the destination is temporary or not
*
* By default DestListMetrics will connect to the broker running on localhost:7676.
* You can use -DimqAddressList attribute to change the host, port and
* transport:
*
* java -DimqAddressList=mq://<host>:<port>/jms DestListMetrics
*/
public class DestListMetrics implements MessageListener {
ConnectionFactory metricConnectionFactory;
Connection metricConnection;
Session metricSession;
MessageConsumer metricConsumer;
Topic metricTopic;
MetricsPrinter mp;
String metricTopicName = null;
int rowsPrinted = 0;
public static void main(String args[]) {
DestListMetrics dlm = new DestListMetrics();
dlm.initPrinter();
dlm.initJMS();
dlm.subscribeToMetric();
}
public DestListMetrics() {
}
/*
* Initializes the class that does the printing, MetricsPrinter.
* See the MetricsPrinter class for details.
*/
private void initPrinter() {
String oneRow[] = new String[ 3 ];
int i = 0;
mp = new MetricsPrinter(3, 2, "-");
oneRow[i++] = "Destination Name";
oneRow[i++] = "Type";
oneRow[i++] = "Is Temporary";
mp.addTitle(oneRow);
}
/**
* Create the Connection and Session etc.
*/
public void initJMS() {
try {
metricConnectionFactory = new com.sun.messaging.ConnectionFactory();
metricConnection = metricConnectionFactory.createConnection();
metricConnection.start();
// creating Session
// Transaction Mode: None
// Acknowledge Mode: Automatic
metricSession = metricConnection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch(Exception e) {
System.err.println("Cannot create metric connection or session: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
public void subscribeToMetric() {
try {
metricTopicName = "mq.metrics.destination_list";
metricTopic = metricSession.createTopic(metricTopicName);
metricConsumer = metricSession.createConsumer(metricTopic);
metricConsumer.setMessageListener(this);
} catch(JMSException e) {
System.err.println("Cannot subscribe to metric topic: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
/*
* When a metric message arrives
* - verify it"s type
* - extract it"s fields
* - print one row of output
*/
public void onMessage(Message m) {
try {
MapMessage mapMsg = (MapMessage)m;
String type = mapMsg.getStringProperty("type");
if (type.equals(metricTopicName)) {
String oneRow[] = new String[ 3 ];
/*
* Extract metrics
*/
for (Enumeration e = mapMsg.getMapNames();
e.hasMoreElements();) {
String metricDestName = (String)e.nextElement();
Hashtable destValues = (Hashtable)mapMsg.getObject(metricDestName);
int i = 0;
oneRow[i++] = (destValues.get("name")).toString();
oneRow[i++] = (destValues.get("type")).toString();
oneRow[i++] = (destValues.get("isTemporary")).toString();
mp.add(oneRow);
}
mp.print();
System.out.println("");
mp.clear();
} else {
System.err.println("Msg received: not destination list metric type");
}
} catch (Exception e) {
System.err.println("onMessage: Exception caught: " + e);
}
}
}
The DestMetrics example is a JMS application that monitors a destination on a Sun Java(tm) System Message Queue broker
/*
* @(#)DestMetrics.java 1.3 04/01/05
*
* Copyright (c) 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.util.Enumeration;
import java.util.Properties;
import javax.jms.*;
/**
* The DestMetrics example is a JMS application that monitors a
* destination on a Sun Java(tm) System Message Queue broker. It does so by
* subscribing to a topic named:
* mq.metrics.destination.queue.<dest_name> OR
* mq.metrics.destination.topic.<dest_name>
* Messages that arrive contain information describing the
* destination such as:
* - number of messages that flowed into this destination
* - number of messages that flowed out of this destination
* - size of message bytes that flowed into this destination
* - size of message bytes that flowed out of this destination
* - etc.
*
* Note that this example does not display all the information
* available in the destination metric message.
*
* This application takes the following arguments:
* -t dest_type Specify required destination type. Valid values
* are "t" or "q".
* -n dest_name Specify required destination name.
*
* By default DestMetrics will connect to the broker running on localhost:7676.
* You can use -DimqAddressList attribute to change the host, port and
* transport:
*
* java -DimqAddressList=mq://<host>:<port>/jms DestMetrics
*/
public class DestMetrics implements MessageListener {
ConnectionFactory metricConnectionFactory;
Connection metricConnection;
Session metricSession;
MessageConsumer metricConsumer;
Topic metricTopic;
MetricsPrinter mp;
String metricTopicName = null;
int rowsPrinted = 0;
public static void main(String args[]) {
String destName = null, destType = null;
for (int i = 0; i < args.length; ++i) {
if (args[i].equals("-n")) {
destName = args[i+1];
} else if (args[i].equals("-t")) {
destType = args[i+1];
}
}
if (destName == null) {
System.err.println("Need to specify destination name with -n");
System.exit(1);
}
if (destType == null) {
System.err.println("Need to specify destination type (t or q) with -t");
System.exit(1);
}
DestMetrics bm = new DestMetrics();
bm.initPrinter(destType, destName);
bm.initJMS();
bm.subscribeToMetric(destType, destName);
}
public DestMetrics() {
}
/*
* Initializes the class that does the printing, MetricsPrinter.
* See the MetricsPrinter class for details.
*/
private void initPrinter(String destType, String destName) {
String oneRow[] = new String[ 11 ], tmp;
int span[] = new int[ 11 ];
int i = 0;
mp = new MetricsPrinter(11, 2, "-", MetricsPrinter.CENTER);
mp.setTitleAlign(MetricsPrinter.CENTER);
i = 0;
span[i++] = 2;
span[i++] = 0;
span[i++] = 2;
span[i++] = 0;
span[i++] = 3;
span[i++] = 0;
span[i++] = 0;
span[i++] = 3;
span[i++] = 0;
span[i++] = 0;
span[i++] = 1;
i = 0;
oneRow[i++] = "Msgs";
oneRow[i++] = "";
oneRow[i++] = "Msg Bytes";
oneRow[i++] = "";
oneRow[i++] = "Msg Count";
oneRow[i++] = "";
oneRow[i++] = "";
oneRow[i++] = "Total Msg Bytes (k)";
oneRow[i++] = "";
oneRow[i++] = "";
oneRow[i++] = "Largest";
mp.addTitle(oneRow, span);
i = 0;
oneRow[i++] = "In";
oneRow[i++] = "Out";
oneRow[i++] = "In";
oneRow[i++] = "Out";
oneRow[i++] = "Current";
oneRow[i++] = "Peak";
oneRow[i++] = "Avg";
oneRow[i++] = "Current";
oneRow[i++] = "Peak";
oneRow[i++] = "Avg";
oneRow[i++] = "Msg (k)";
mp.addTitle(oneRow);
}
/**
* Create the Connection and Session etc.
*/
public void initJMS() {
try {
metricConnectionFactory = new com.sun.messaging.ConnectionFactory();
metricConnection = metricConnectionFactory.createConnection();
metricConnection.start();
// creating Session
// Transaction Mode: None
// Acknowledge Mode: Automatic
metricSession = metricConnection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch(Exception e) {
System.err.println("Cannot create metric connection or session: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
public void subscribeToMetric(String destType, String destName) {
try {
if (destType.equals("q")) {
metricTopicName = "mq.metrics.destination.queue." + destName;
} else {
metricTopicName = "mq.metrics.destination.topic." + destName;
}
metricTopic = metricSession.createTopic(metricTopicName);
metricConsumer = metricSession.createConsumer(metricTopic);
metricConsumer.setMessageListener(this);
} catch(JMSException e) {
System.err.println("Cannot subscribe to metric topic: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
/*
* When a metric message arrives
* - verify it"s type
* - extract it"s fields
* - print one row of output
*/
public void onMessage(Message m) {
try {
MapMessage mapMsg = (MapMessage)m;
String type = mapMsg.getStringProperty("type");
if (type.equals(metricTopicName)) {
String oneRow[] = new String[ 11 ];
int i = 0;
/*
* Extract destination metrics
*/
oneRow[i++] = Long.toString(mapMsg.getLong("numMsgsIn"));
oneRow[i++] = Long.toString(mapMsg.getLong("numMsgsOut"));
oneRow[i++] = Long.toString(mapMsg.getLong("msgBytesIn"));
oneRow[i++] = Long.toString(mapMsg.getLong("msgBytesOut"));
oneRow[i++] = Long.toString(mapMsg.getLong("numMsgs"));
oneRow[i++] = Long.toString(mapMsg.getLong("peakNumMsgs"));
oneRow[i++] = Long.toString(mapMsg.getLong("avgNumMsgs"));
oneRow[i++] = Long.toString(mapMsg.getLong("totalMsgBytes")/1024);
oneRow[i++] = Long.toString(mapMsg.getLong("peakTotalMsgBytes")/1024);
oneRow[i++] = Long.toString(mapMsg.getLong("avgTotalMsgBytes")/1024);
oneRow[i++] = Long.toString(mapMsg.getLong("peakMsgBytes")/1024);
mp.add(oneRow);
if ((rowsPrinted % 20) == 0) {
mp.print();
} else {
mp.print(false);
}
rowsPrinted++;
mp.clear();
} else {
System.err.println("Msg received: not broker metric type");
}
} catch (Exception e) {
System.err.println("onMessage: Exception caught: " + e);
}
}
}
The mqping utility is similar to the Unix ping utility in some regards
/*
* @(#)mqping.java 1.1 04/06/07
*
* @version mqping.java 04/06/07 1.1
*
* Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
@(#)README 1.4 03/22/05
================================================================================
mqping utility
Description
-----------
The mqping utility is similar to the Unix ping utility in some regards.
With mqping, messages are sent to and received from a running broker.
The utility measures the round trip time. The utility allows the user
to control the size of the message, the destination type, delivery mode
and send interval.
Files
-----
mqping.java Source file for this example.
*.class Prebuilt Java class files for this example.
README This file.
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer"s Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:/opt/sun/mq/share/lib/imq.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac mqping.java
Running the example
-------------------
In the simplest form the mqping utility can be run with no options:
java mqping
This utility takes the following arguments:
-t dest_type Specify the optional destination type. Valid values
are "t" or "q". Default: "q"
-r Optionally indicate the message is persistent.
Not specifying this option indicates the message
should not be persisted.
-s size Specify the optional size of the messages in bytes.
Default: 1024
-i delay The interval (in seconds) between successive
transmissions. Default: 0 (no delay)
By default mqping will connect to the broker running on localhost:7676.
You can use -DimqAddressList attribute to change the host, port and
transport:
java -DimqAddressList=mq://<host>:<port>/jms mqping
/*
* @(#)mqping.java 1.1 04/06/07
*
* @version mqping.java 04/06/07 1.1
*
* Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
import java.util.*;
/**
*
* Version 1.0
*
* The mqping utility is similar to the Unix ping utility in some regards.
* With mqping, messages are sent to and received from a running broker.
* The utility measures the round trip time. The utility allows the user
* to control the size of the message, the destination type, delivery mode
* and send interval.
*
* This utility takes the following arguments:
* -t dest_type Specify the optional destination type. Valid values
* are "t" or "q". Default: "q"
* -r Optionally indicate the message is persistent.
* Not specifying this option indicates the message
* should not be persisted.
* -s size Specify the optional size of the messages in bytes.
* Default: 1024
* -i delay The interval (in seconds) between successive
* transmissions. Default: 0 (no delay)
*
* By default mqping will connect to the broker running on localhost:7676.
* You can use -DimqAddressList attribute to change the host, port and
* transport:
*
* java mqping -DimqAddressList=mq://<host>:<port>/jms
*
*/
public class mqping {
ConnectionFactory connectionFactory;
Connection connection;
Session session;
MessageConsumer receiver;
String destType;
Destination dest;
boolean interrupt = false;
int max = 0, min = 1000000, totalms = 0, sent = 0, recv = 0;
public static void main(String args[]) {
String host = "localhost";
int size = 1024,
deliveryMode = DeliveryMode.NON_PERSISTENT,
sleepTime = 0;
mqping ping;
ping = new mqping();
ping.destType = new String("q");
// Process the args
for (int i = 0; i < args.length; ++i) {
if (args[i].equals("-t")) {
ping.destType = args[i+1];
i++;
if (!ping.destType.equals("q") && !ping.destType.equals("t")) {
System.err.println("Problems processing -t <dest_type>" +
" string.");
Usage();
}
} else if (args[i].equals("-r")) {
deliveryMode = DeliveryMode.PERSISTENT;
} else if (args[i].equals("-s")) {
try {
size = Integer.parseInt(args[i+1]);
if (size < 0) {
System.err.println("Value of -s <size> less than 0: ");
Usage();
}
i++;
} catch (Exception e) {
System.err.println("Problems processing -s <size> string.");
Usage();
}
} else if (args[i].equals("-i")) {
try {
sleepTime = Integer.parseInt(args[i+1]);
if (sleepTime < 0) {
System.err.println("Value of -i <delay> less than 0: ");
Usage();
}
i++;
} catch (Exception e) {
System.err.println("Problems processing -i <delay> string.");
Usage();
}
} else
Usage();
}
// Initialize the connection, session and destination.
ping.initJMS();
String address = System.getProperty("imqAddressList");
if (address != null) {
int i = address.indexOf("/");
int j = address.lastIndexOf(":");
if (j >= i+2) {
host = address.substring(i+2, j);
}
}
// Establish a shutdown hook to print ping stats.
Thread hook = new PingShutdownHook(host, ping);
try {
Runtime.getRuntime().addShutdownHook(hook);
} catch (IllegalArgumentException e) {
System.err.println("Cannot establish a shutdown hook: "
+ e.getMessage());
System.exit(1);
} catch (java.lang.IllegalStateException e) {
// Do nothing.
} catch (SecurityException e) {
System.err.println("Cannot establish a shutdown hook: "
+ e.getMessage());
System.exit(1);
}
// Ping the broker.
ping.ping(host, deliveryMode, size, sleepTime);
try {
if (ping.interrupt != true)
ping.connection.close();
} catch (JMSException e) {
System.err.println("Cannot close connection: "
+ e.getMessage());
System.exit(1);
}
}
public static void Usage () {
System.out.print(
"Usage: java mqping [-t t/q] [-r] [-s size]");
System.out.println(" [-i delay]");
System.out.print(" -t: t = send to topic, q = send to queue");
System.out.println(" Default: q");
System.out.println(
" -r: send persistent messages. Default: non-persistent");
System.out.println(
" -s: size of messages to send in bytes. Default: 1024");
System.out.print(
" -i: the interval (in seconds) between successive");
System.out.println(
" transmissions. Default: 0");
System.exit(1);
}
public mqping() {
}
private void initJMS() {
Random rand;
try {
rand = new Random(Calendar.getInstance().getTimeInMillis());
connectionFactory = new com.sun.messaging.ConnectionFactory();
connection = connectionFactory.createConnection();
// For Durable Subs we need to set the client ID but for this
// application we really don"t need to use the same client ID
// from invocation to invocation.
if (destType.equals("t"))
connection.setClientID("MQPing" + rand.nextInt(1000000));
// We don"t really care about the Ack mode as that is not
// part of the measurement.
session = connection.createSession(false,
Session.DUPS_OK_ACKNOWLEDGE);
if (destType.equals("q"))
dest = session.createQueue("MQPing" + rand.nextInt(1000000));
else
dest = session.createTopic("MQPing" + rand.nextInt(1000000));
connection.start();
} catch (Exception e) {
System.err.println("Problems creating JMS resources: "
+ e.getMessage());
System.exit(1);
}
}
private void ping(String host, int deliveryMode, int size, int sleepTime) {
MessageProducer sender;
TopicSubscriber sub;
Message echo;
long currentTime;
int diffms = 0;
try {
sender = session.createProducer(dest);
if (destType.equals("q"))
receiver = session.createConsumer(dest);
else {
sub = session.createDurableSubscriber((Topic)dest, "MQPing");
receiver = (MessageConsumer) sub;
}
BytesMessage msg = session.createBytesMessage();
byte[] data = new byte[size];
msg.writeBytes(data, 0, data.length);
System.out.println("PING " + host + ": " + size + " data bytes");
// Ping until we receive ^C
for (int i = 1; interrupt == false; i++) {
msg.setLongProperty("sendTime",
Calendar.getInstance().getTimeInMillis());
msg.setLongProperty("sequence", i);
synchronized(this) {
// Send and Receive the message
sender.send(msg, deliveryMode, 1, 20000);
echo = receiver.receive();
currentTime = Calendar.getInstance().getTimeInMillis();
diffms =
(int)(currentTime - echo.getLongProperty("sendTime"));
}
System.out.println(
size + " bytes from " + host +
": sequence=" + echo.getLongProperty("sequence") +
". time=" + diffms + "ms.");
// Process stats
sent++; recv++;
totalms += diffms;
if (diffms < min)
min = diffms;
if (diffms > max)
max = diffms;
if (sleepTime != 0)
sleep(sleepTime * 1000);
}
} catch (InvalidDestinationException e) {
System.err.println("Invalid Destination: " + e.getMessage());
System.exit(1);
} catch (JMSException e) {
if (interrupt != true) {
System.err.println("Error managing JMS resources: "
+ e.getMessage());
System.exit(1);
}
} catch (UnsupportedOperationException e) {
System.err.println("Destination not properly specified: "
+ e.getMessage());
System.exit(1);
} catch (Exception e) {
System.err.println("Error: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
/**
* Sleep for a specified time.
* @param time Time in milliseconds to wait.
*/
public void sleep (int time) {
try {
Thread.sleep(time);
}
catch (Exception e) {
}
}
}
/**
* A shutdown hook is called before the VM is going to exit.
* Display stats here.
*/
class PingShutdownHook extends Thread {
mqping ping;
PingShutdownHook(String host, mqping ping) {
super(host);
this.ping = ping;
}
public void run() {
int loss = 0, avg = 0;
synchronized(ping) {
ping.interrupt = true;
try {
ping.receiver.close();
// We never need to keep the durable around beyond the life of
// this application.
if (ping.destType.equals("t"))
ping.session.unsubscribe("MQPing");
ping.connection.close();
} catch (JMSException e) {
System.err.println("Cannot close JMS resources: "
+ e.getMessage());
System.exit(1);
}
}
loss = (int) (((ping.sent - ping.recv)/ping.sent) * 100);
avg = (int) (ping.totalms/ping.recv);
System.out.println("----" + getName() + " PING Statistics----");
System.out.println(ping.sent + " messages transmitted, " + ping.recv +
" messages received, " + loss + "% message loss");
System.out.println("round-trip (ms) min/avg/max = " + ping.min +
"/" + avg + "/" + ping.max);
}
}
The simplest form of the publish/subscribe model: the producer publishes a message, and the consumer reads it using a synchronous receive
/*
* @(#)SynchTopicExample.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The SynchTopicExample class demonstrates the simplest form of the
* publish/subscribe model: the producer publishes a message, and the
* consumer reads it using a synchronous receive.
* <p>
* The program contains a SimpleProducer class, a SynchConsumer class, a
* main method, and a method that runs the consumer and producer
* threads.
* <p>
* Specify a topic name on the command line when you run the program.
* <p>
* The program calls methods in the SampleUtilities class.
*
* @author Kim Haase
* @version 1.7, 08/18/00
*/
public class SynchTopicExample {
String topicName = null;
int exitResult = 0;
/**
* The SynchConsumer class fetches a single message from a topic using
* synchronous message delivery.
*
* @author Kim Haase
* @version 1.7, 08/18/00
*/
public class SynchConsumer extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
MessageConsumer msgConsumer = null;
final boolean NOLOCAL = true;
TextMessage inMessage = null;
TextMessage outMessage = null;
MessageProducer msgProducer = null;
/*
* Obtain connection factory.
* Create connection.
* Create session from connection; false means session is not
* transacted.
* Obtain topic name.
*/
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create consumer, then start message delivery. Consumer is
* non-local so that it won"t receive the message we publish.
* Wait for text message to arrive, then display its contents.
* Close connection and exit.
*/
try {
msgConsumer =
session.createConsumer(topic, null, NOLOCAL);
connection.start();
inMessage = (TextMessage) msgConsumer.receive();
System.out.println("CONSUMER THREAD: Reading message: "
+ inMessage.getText());
/*
* Notify producer that we received a message and it
* can stop broadcasting.
*/
msgProducer = session.createProducer(topic);
outMessage = session.createTextMessage();
outMessage.setText("Done");
msgProducer.send(outMessage);
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The SimpleProducer class publishes a single message to a topic.
*
* @author Kim Haase
* @version 1.7, 08/18/00
*/
public class SimpleProducer extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
MessageConsumer producerControlConsumer = null;
final boolean NOLOCAL = true;
MessageProducer msgProducer = null;
TextMessage sentMessage = null;
final String MSG_TEXT = new String("Here is a message ");
Message receivedMessage = null;
/*
* Obtain connection factory.
* Create connection.
* Create session from connection; false means session is not
* transacted.
* Obtain topic name.
*/
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create non-local consumer to receive "Done" message from
* another connection; start delivery.
* Create producer and text message.
* Set message text, display it, and publish message.
* Close connection and exit.
*/
try {
producerControlConsumer =
session.createConsumer(topic, null, NOLOCAL);
connection.start();
/*
* Publish a message once per second until consumer
* reports that it has finished receiving messages.
*/
msgProducer = session.createProducer(topic);
sentMessage = session.createTextMessage();
for (int i = 1; receivedMessage == null; i++) {
sentMessage.setText(MSG_TEXT + i);
System.out.println("PRODUCER THREAD: Publishing message: "
+ sentMessage.getText());
msgProducer.send(sentMessage);
try { Thread.sleep(1000); } catch (InterruptedException ie){}
receivedMessage = producerControlConsumer.receiveNoWait();
}
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* Instantiates the consumer and producer classes and starts their
* threads.
* Calls the join method to wait for the threads to die.
* <p>
* It is essential to start the consumer before starting the producer.
* In the publish/subscribe model, a consumer can ordinarily receive only
* messages published while it is active.
*/
public void run_threads() {
SynchConsumer synchConsumer = new SynchConsumer();
SimpleProducer simpleProducer = new SimpleProducer();
synchConsumer.start();
simpleProducer.start();
try {
synchConsumer.join();
simpleProducer.join();
} catch (InterruptedException e) {}
}
/**
* Reads the topic name from the command line and displays it. The
* topic must have been created by the jmsadmin tool.
* Calls the run_threads method to execute the program threads.
* Exits program.
*
* @param args the topic used by the example
*/
public static void main(String[] args) {
SynchTopicExample ste = new SynchTopicExample();
if (args.length != 1) {
System.out.println("Usage: java SynchTopicExample <topic_name>");
System.exit(1);
}
ste.topicName = new String(args[0]);
System.out.println("Topic name is " + ste.topicName);
ste.run_threads();
SampleUtilities.exit(ste.exitResult);
}
}
The TopicSelectors class demonstrates the use of multiple subscribers and message selectors
/*
* @(#)TopicSelectors.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.util.*;
import javax.jms.*;
/**
* The TopicSelectors class demonstrates the use of multiple
* subscribers and message selectors.
* <p>
* The program contains a Publisher class, a Subscriber class with a listener
* class, a main method, and a method that runs the subscriber and publisher
* threads.
* <p>
* The Publisher class publishes 30 messages of 6 different types, randomly
* selected, then publishes a "Finished" message. The program creates four
* instances of the Subscriber class, one for each of three types and one that
* listens for the "Finished" message. Each subscriber instance uses a
* different message selector to fetch messages of only one type. The publisher
* displays the messages it sends, and the listener displays the messages that
* the subscribers receive. Because all the objects run in threads, the
* displays are interspersed when the program runs.
* <p>
* Specify a topic name on the command line when you run the program. The
* program also uses a queue named "controlQueue", which should be created
* before you run the program.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class TopicSelectors {
final String CONTROL_QUEUE = "controlQueue";
String topicName = null;
static final String MESSAGE_TYPES[] =
{"Nation/World", "Metro/Region", "Business",
"Sports", "Living/Arts", "Opinion",
// always last type
"Finished"
};
static final String END_OF_MESSAGE_STREAM_TYPE =
MESSAGE_TYPES[MESSAGE_TYPES.length-1];
int exitResult = 0;
/**
* The Publisher class publishes a number of messages. For each, it
* randomly chooses a message type. It creates a message and sets its
* text to a message that indicates the message type.
* It also sets the client property NewsType, which the Subscriber
* objects use as the message selector.
* After a pause to allow the subscribers to get all the messages, the
* publisher sends a final message with a NewsType of "Finished", which
* signals the end of the messages.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class Publisher extends Thread {
final int NUM_SUBSCRIBERS;
final int ARRSIZE = 6;
public Publisher(int numSubscribers) {
NUM_SUBSCRIBERS = numSubscribers;
}
/**
* Chooses a message type by using the random number generator
* found in java.util.
*
* @return the String representing the message type
*/
public String chooseType() {
int whichMsg;
Random rgen = new Random();
whichMsg = rgen.nextInt(ARRSIZE);
return MESSAGE_TYPES[whichMsg];
}
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
MessageProducer msgProducer = null;
TextMessage message = null;
int numMsgs = ARRSIZE * 5;
String messageType = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* After synchronizing with subscriber, create publisher.
* Create and send news messages.
* Send end-of-messages message.
*/
try {
/*
* Synchronize with subscribers. Wait for messages indicating
* that all subscribers are ready to receive messages.
*/
try {
SampleUtilities.receiveSynchronizeMessages("PUBLISHER THREAD: ",
CONTROL_QUEUE,
NUM_SUBSCRIBERS);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
msgProducer = session.createProducer(topic);
message = session.createTextMessage();
for (int i = 0; i < numMsgs; i++) {
messageType = chooseType();
message.setStringProperty("NewsType", messageType);
message.setText("Item " + i + ": " + messageType);
System.out.println("PUBLISHER THREAD: Setting message text to: "
+ message.getText());
msgProducer.send(message);
}
message.setStringProperty("NewsType", END_OF_MESSAGE_STREAM_TYPE);
message.setText("That"s all the news for today.");
System.out.println("PUBLISHER THREAD: Setting message text to: "
+ message.getText());
msgProducer.send(message);
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* Each instance of the Subscriber class creates a subscriber that uses
* a message selector that is based on the string passed to its
* constructor.
* It registers its message listener, then starts listening
* for messages. It does not exit until the message listener sets the
* variable done to true, which happens when the listener gets the last
* message.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class Subscriber extends Thread {
String whatKind;
int subscriberNumber;
/**
* The MultipleListener class implements the MessageListener interface
* by defining an onMessage method for the Subscriber class.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
private class MultipleListener implements MessageListener {
final SampleUtilities.DoneLatch monitor =
new SampleUtilities.DoneLatch();
/**
* Displays the message text.
* If the value of the NewsType property is "Finished", the message
* listener sets its monitor state to all done processing messages.
*
* @param inMessage the incoming message
*/
public void onMessage(Message inMessage) {
TextMessage msg = (TextMessage) inMessage;
String newsType;
try {
System.out.println("SUBSCRIBER " + subscriberNumber
+ " THREAD: Message received: "
+ msg.getText());
newsType = msg.getStringProperty("NewsType");
if (newsType.equals(TopicSelectors.END_OF_MESSAGE_STREAM_TYPE)) {
System.out.println("SUBSCRIBER " + subscriberNumber
+ " THREAD: Received finished-publishing message");
monitor.allDone();
}
} catch(JMSException e) {
System.out.println("Exception in onMessage(): "
+ e.toString());
}
}
}
/**
* Constructor. Sets whatKind to indicate the type of
* message this Subscriber object will listen for; sets
* subscriberNumber based on Subscriber array index.
*
* @param str a String from the MESSAGE_TYPES array
* @param num the index of the Subscriber array
*/
public Subscriber(String str, int num) {
whatKind = str;
subscriberNumber = num + 1;
}
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
String selector = null;
MessageConsumer msgConsumer = null;
MultipleListener multipleListener = new MultipleListener();
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create subscriber with message selector.
* Start message delivery.
* Send synchronize message to publisher, then wait till all
* messages have arrived.
* Listener displays the messages obtained.
*/
try {
selector = new String("NewsType = "" + whatKind + """ +
" OR NewsType = "" + END_OF_MESSAGE_STREAM_TYPE + """);
System.out.println("SUBSCRIBER " + subscriberNumber
+ " THREAD: selector is \"" + selector + "\"");
msgConsumer =
session.createConsumer(topic, selector, false);
msgConsumer.setMessageListener(multipleListener);
connection.start();
// Let publisher know that subscriber is ready.
try {
SampleUtilities.sendSynchronizeMessage("SUBSCRIBER "
+ subscriberNumber
+ " THREAD: ",
CONTROL_QUEUE);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Asynchronously process appropriate news messages.
* Block until publisher issues a finished message.
*/
multipleListener.monitor.waitTillDone();
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* Creates an array of Subscriber objects, one for each of three message
* types including the Finished type, and starts their threads.
* Creates a Publisher object and starts its thread.
* Calls the join method to wait for the threads to die.
*/
public void run_threads() {
final int NUM_SUBSCRIBERS = 3;
Subscriber subscriberArray[] = new Subscriber[NUM_SUBSCRIBERS];
Publisher publisher = new Publisher(NUM_SUBSCRIBERS);
subscriberArray[0] = new Subscriber(MESSAGE_TYPES[2], 0);
subscriberArray[0].start();
subscriberArray[1] = new Subscriber(MESSAGE_TYPES[3], 1);
subscriberArray[1].start();
subscriberArray[2] = new Subscriber(MESSAGE_TYPES[4], 2);
subscriberArray[2].start();
publisher.start();
for (int i = 0; i < subscriberArray.length; i++) {
try {
subscriberArray[i].join();
} catch (InterruptedException e) {}
}
try {
publisher.join();
} catch (InterruptedException e) {}
}
/**
* Reads the topic name from the command line, then calls the
* run_threads method to execute the program threads.
*
* @param args the topic used by the example
*/
public static void main(String[] args) {
TopicSelectors ts = new TopicSelectors();
if (args.length != 1) {
System.out.println("Usage: java TopicSelectors <topic_name>");
System.exit(1);
}
ts.topicName = new String(args[0]);
System.out.println("Topic name is " + ts.topicName);
ts.run_threads();
SampleUtilities.exit(ts.exitResult);
}
}
The UniversalClient example is a basic "client" application that uses the JMS 1.1 APIs
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
================================================================================
@(#)README 1.1 06/01/05
================================================================================
UniversalClient example
Description
-----------
The UniversalClient example is a basic "client" application that uses the JMS 1.1 APIs.
It uses JMS Message Producer and Consumer to send and receive message.
UniversalClient.java does not use JNDI and relies on
the feature by which a broker can "auto-create" the destinations
desired by the user. The bulk of the application deals with the
user interface and the JMS related code is fairly straightforward.
Files
-----
UniversalClient.java Source file for this example.
*.class Prebuilt Java class files for this example.
README This file.
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer"s Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac UniversalClient.java
Running the example
-------------------
Run the following:
java UniversalClient
The application comes up not connected to any jms session.
To connect to a broker, bring down the "Actions" menu and
select the "Connect ..." menu item. A dialog will appear to
provide broker hostname, port, username, password, clientID
etc
To disconnect from a given broker host: port bring down the
"Actions" menu and select the "Disconnect" menu item
Once the application is connected, one can send message using
a message producer. To create a producer bring down the "Actions"
menu and select the "Send Message..." menu item. The Send Message
dialog box will come up, where destination name,type and message
size,ttl etc can be specified while sending message.
To stop message sender bring down the "Actions" menu and select
the "Stop Message Sender" menu item
To receive message bring down the "Actions" menu and select the
"Receive Message..." menu item. The receive message dialog box
will come up where destination name, message consumer type and
message selector can be specified.
To stop message receiver bring down the "Actions" menu and select
the "Stop Message Receiver" menu item.
The received message are displayed on a Message Table. To see the
details of a message double click on a row of a message table or
select a row of a message table and click on "Message Details" button.
To start auto scrolling of message table i.e to always see the last
message received, drag the message table vertical scroll bar at the
bottom. To stop auto scrolling drag the message table vertical scroll
bar else where.
To clear existing messages in the message table bring down the "Actions"
menu and select the "Clear Messages" menu item.
The status bar at the bottom shows Message Queue Client Runtime
Connection Notification And Connection related log
To exit from the application, bring down the "console" menu and
click "exit"
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
//package examples.applications.uclient;
import com.sun.messaging.jms.notification.ConnectionReconnectedEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.ResourceAllocationException;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TransactionRolledBackException;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
* The UniversalClient example is a basic "client" application that uses the JMS 1.1 APIs.
* It uses JMS Message Producer and Consumer to send and receive message.
*
* When the application is launched, use the "Universal Client"Actions menu to start or connect to
* a boker.
*
* The broker host port can be provided using the GUI. Once the client is connected one can send
* jms messages to any number of destination Topic or Queue.
*
* Once the Producer send messages to a destination of the given boker,
* one can create a consumer for the same destination which receives the messages
* and display them in a Message Table.
*
* For destination of type Queue one can simply receive message either by using transacted session
* or by using non-transacted session
*
* For topic type destination the one can create a durable Topic subscriber for a given
* topic with a given selector. One can receive message using the topic subscriber created during the
* first receive message button click, but if at later stage one changes the topic selector or the
* transaction type a new durable topic selector is created
*
*
* One can see the details of the message received, by using the "Message Details" button.
*
*
* @author Sujit Biswas
*/
public class UniversalClient implements UniversalClientConstants,
ExceptionListener {
// Connection, factory and session..
private ConnectionFactory myConnFactory;
private Connection myConn;
private Session myProducerSession;
private Session myConsumerSession;
private MessageProducer myProducer;
private MessageConsumer myConsumer;
private Destination myDestination;
private boolean connected = false;
//data structures
private HashMap mySessionMap = new HashMap();
private HashMap myProducerMap = new HashMap();
//username, hostname
private String userName;
private String password;
private String hostName = "localhost";
private String clientID;
private int port = 7676;
// main frame
private JFrame frame;
//MenuBar and MenuItems
private JMenuBar menuBar;
private JMenuItem connectItem;
private JMenuItem disconnectItem;
private JMenuItem clearItem;
private JMenuItem exitItem;
private JMenuItem sendMsgItem;
private JMenuItem sendMsgStopItem;
private JMenuItem rcvMsgItem;
private JMenuItem rcvMsgStopItem;
//connection dialog box
private ConnectionDialogBox connDialogB;
private JButton connectB;
private JButton connCancelB;
//send message dialog box
private SendMessageDialogBox sendMsgDialogB;
private JButton sendMsgB;
private JButton sendMsgCancelB;
//Footer panel
private JPanel footerPanel;
private JLabel footerLabel;
private boolean footerInUse;
//message table to show the received message
private JTable msgTable;
private JScrollPane msgTableScrollPane;
private boolean scrollingON;
//top panel
private double msgProductionRate;
private JPanel topPanel;
private JLabel msgProductionRateLabel;
private JLabel hostPortLabel;
private JLabel clientIDLabel;
private JProgressBar sendMsgProgressBar = new JProgressBar();
//Message details frame
private JFrame detailsFrame;
private PropertyPanel msgDetailsHeaderPanel;
private PropertyPanel msgDetailsPropertyPanel;
private PropertyPanel msgDetailsBodyPanel;
//receive messages dialog box
private ReceiveMessageDialogBox receiveMsgDialogB;
private JButton receiveMsgB;
private JButton receiveMsgCancelB;
//status area
StatusArea statusArea;
//stop msg sender
private boolean msgSenderStopped;
// stop msg receiver
private boolean msgReceiverStopped;
public UniversalClient() {
userName = "guest";
password = "guest";
clientID = System.getProperty("universalclient.cid", null);
if (clientID == null) {
clientID = System.getProperty("user.name", "UClient-ID");
}
createAndShowGUI();
Thread statusReporter = new StatusReportingThread();
statusReporter.setPriority(Thread.MIN_PRIORITY);
statusReporter.setDaemon(true);
statusReporter.start();
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private void createAndShowGUI() {
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
//Make sure we have nice window decorations.
//JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the window.
frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
//create Menubar
menuBar = createMenuBar();
frame.setJMenuBar(menuBar);
//Add the top panel
topPanel = createTopPanel();
frame.getContentPane().add(topPanel, BorderLayout.NORTH);
//create message table panel
JPanel tablePanel = createTablePanel();
//create footer Panel
createFooterPanel();
//add footer to message table
tablePanel.add(footerPanel, BorderLayout.SOUTH);
//create status area
statusArea = new StatusArea();
statusArea.appendText(
"# Message Queue Client Runtime Connection Notification And Connection related log");
/*
* Create another split pane containing the table panel above
* and the status area.
*/
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setOneTouchExpandable(true);
splitPane.setTopComponent(tablePanel);
splitPane.setBottomComponent(statusArea);
splitPane.setResizeWeight(0.9);
frame.getContentPane().add(splitPane, BorderLayout.CENTER);
//set size of mainframe
setSize();
//Display the window.
frame.setVisible(true);
}
/**
* sets the size of the main frame
*/
private void setSize() {
int relativeSize = 10; //with base = 15
String osName = System.getProperty("os.name", "");
if (osName.indexOf("Windows") >= 0) {
relativeSize = 12;
}
Toolkit tk = frame.getToolkit();
Dimension d = tk.getScreenSize();
frame.setSize((d.width * relativeSize) / 15,
(d.height * relativeSize) / 15);
frame.setLocation(d.width / 8, d.height / 16);
}
/**
* Create menubar for application.
*/
private JMenuBar createMenuBar() {
JMenuBar mb = new JMenuBar();
JMenu consoleMenu = (JMenu) mb.add(new JMenu("Universal Client"));
consoleMenu.setMnemonic("C");
JMenu actionsMenu = (JMenu) mb.add(new JMenu("Actions"));
actionsMenu.setMnemonic("A");
connectItem = addMenuItem(actionsMenu, "Connect ...");
connectItem.setMnemonic("C");
disconnectItem = addMenuItem(actionsMenu, "Disconnect");
disconnectItem.setMnemonic("D");
actionsMenu.add(new JSeparator());
sendMsgItem = addMenuItem(actionsMenu, "Send Message ...");
sendMsgItem.setMnemonic("M");
sendMsgStopItem = addMenuItem(actionsMenu, "Stop Msg Sender");
sendMsgStopItem.setMnemonic("S");
actionsMenu.add(new JSeparator());
rcvMsgItem = addMenuItem(actionsMenu, "Receive Message ...");
rcvMsgItem.setMnemonic("R");
rcvMsgStopItem = addMenuItem(actionsMenu, "Stop Msg Receiver");
rcvMsgStopItem.setMnemonic("t");
actionsMenu.add(new JSeparator());
clearItem = addMenuItem(actionsMenu, "Clear Messages");
clearItem.setMnemonic("e");
exitItem = addMenuItem(consoleMenu, "Exit");
exitItem.setMnemonic("x");
exitItem.setAccelerator(KeyStroke.getKeyStroke("Q", 2));
disconnectItem.setEnabled(false);
connectItem.addActionListener(new ConnectionPopUpListener());
disconnectItem.addActionListener(new DisConnectionListener());
sendMsgItem.addActionListener(new SendMessagePopUpListener());
sendMsgItem.setEnabled(false);
sendMsgStopItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setMsgSenderStopped(true);
}
});
sendMsgStopItem.setEnabled(false);
rcvMsgItem.addActionListener(new ReceiveMessagePopUpListener());
rcvMsgItem.setEnabled(false);
rcvMsgStopItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stopMsgReceiver();
}
});
rcvMsgStopItem.setEnabled(false);
clearItem.addActionListener(new ClearMessageListener());
exitItem.addActionListener(new ExitListener());
return (mb);
}
/**
* adds menu item to menu
*/
private JMenuItem addMenuItem(JMenu menu, String itemStr) {
JMenuItem item = (JMenuItem) menu.add(newJMenuItem(itemStr));
return item;
}
/**
* returns a new JMenuItem
*/
private JMenuItem newJMenuItem(String s) {
JMenuItem jmi = new JMenuItem(s);
return jmi;
}
/**
* create table Panel for message received
*/
private JPanel createTablePanel() {
JPanel tPanel = new JPanel();
tPanel.setLayout(new BorderLayout());
msgTable = new JTable(new MsgTable());
msgTable.addMouseListener(new TableMouseListener());
TableColumn column = msgTable.getColumnModel().getColumn(1);
column.setPreferredWidth(125);
column = msgTable.getColumnModel().getColumn(2);
column.setPreferredWidth(85);
column = msgTable.getColumnModel().getColumn(3);
column.setPreferredWidth(95);
column = msgTable.getColumnModel().getColumn(4);
column.setPreferredWidth(15);
column = msgTable.getColumnModel().getColumn(5);
column.setPreferredWidth(15);
column = msgTable.getColumnModel().getColumn(6);
column.setPreferredWidth(40);
msgTableScrollPane = new JScrollPane(msgTable);
msgTableScrollPane.setAutoscrolls(true);
MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
((JScrollBar) e.getSource()).scrollRectToVisible(r);
int maxHeight = msgTable.getVisibleRect().height;
if (e.getY() > (maxHeight - 30)) {
setScrollingON(true);
} else {
setScrollingON(false);
}
}
};
msgTableScrollPane.getVerticalScrollBar().addMouseMotionListener(doScrollRectToVisible);
msgTableScrollPane.getVerticalScrollBar().setToolTipText("Drag to Bottom to Start auto scroll, to Stop autoscroll Drag else where");
tPanel.add(new JLabel("Received Message Table", SwingConstants.CENTER),
BorderLayout.NORTH);
tPanel.add(msgTableScrollPane, BorderLayout.CENTER);
tPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
return tPanel;
}
/**
* create top Panel for production related statistics
*/
private JPanel createTopPanel() {
msgProductionRate = Double.NaN;
topPanel = new JPanel(new BorderLayout());
topPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
JLabel l = new JLabel("Connection & Message Production",
SwingConstants.CENTER);
l.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
topPanel.add(BorderLayout.NORTH, l);
JPanel dummyP = new JPanel(new BorderLayout());
clientIDLabel = new JLabel();
msgProductionRateLabel = new JLabel();
hostPortLabel = new JLabel();
dummyP.add(BorderLayout.NORTH, clientIDLabel);
dummyP.add(BorderLayout.CENTER, hostPortLabel);
dummyP.add(BorderLayout.SOUTH, msgProductionRateLabel);
topPanel.add(BorderLayout.WEST, dummyP);
setClientID();
setMsgProductionRate("Not Available");
setHostPort("Client Not Connected");
dummyP = new JPanel(new BorderLayout());
setSendMsgProgressBar(0, "");
dummyP.add(BorderLayout.CENTER, sendMsgProgressBar);
topPanel.add(BorderLayout.SOUTH, dummyP);
topPanel.setPreferredSize(new Dimension(0, 95));
return topPanel;
}
/**
* Main
*/
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
UniversalClient uc = new UniversalClient();
}
});
}
/**
* shows connection dialog box to connect to a broker
*/
private void popUpConnDialogBox() {
if (connDialogB == null) {
connDialogB = new ConnectionDialogBox(frame);
connectB = connDialogB.getConnectButton();
connectB.addActionListener(new ConnectionListener());
connCancelB = connDialogB.getCancelButton();
connCancelB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
connDialogB.setVisible(false);
}
});
}
connDialogB.setUserName(userName);
connDialogB.setPassword(password);
connDialogB.setClientID(clientID);
connDialogB.setVisible(true);
}
/**
* shows Send Message dialog box for sending one or more message
*/
private void popUpSendMessageDialogBox() {
if (sendMsgDialogB == null) {
sendMsgDialogB = new SendMessageDialogBox(frame);
sendMsgB = sendMsgDialogB.getSendButton();
sendMsgB.addActionListener(new SendMessageListener());
sendMsgCancelB = sendMsgDialogB.getCancelButton();
sendMsgCancelB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendMsgDialogB.setVisible(false);
}
});
}
sendMsgDialogB.setVisible(true);
}
/**
* shows Receive Message dialog box for receiving one or more message
*/
private void popUpReceiveMessageDialogBox() {
if (receiveMsgDialogB == null) {
receiveMsgDialogB = new ReceiveMessageDialogBox(frame);
receiveMsgB = receiveMsgDialogB.getReceiveButton();
receiveMsgB.addActionListener(new ReceiveMessageListener());
receiveMsgCancelB = receiveMsgDialogB.getCancelButton();
receiveMsgCancelB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
receiveMsgDialogB.setVisible(false);
}
});
}
receiveMsgDialogB.setVisible(true);
}
/**
* Connect to a broker given a host port, createConnection method
* Performs the actual connect.
*/
private void doConnect() {
if (connected()) {
return;
}
if (createConnection() == false) {
errorMessage("Unable to create A session. " +
"Please verify a broker is running");
return;
}
setUpUIAfterConnection();
printToStatusArea("Successfully Connected to " + getHostName() + ":" +
getPort());
}
/**
* setup UI and other flags once a connection is either
* by user or MQ client runtime auto reconnect
*
*/
private void setUpUIAfterConnection() {
setConnected(true);
connectItem.setEnabled(false);
disconnectItem.setEnabled(true);
sendMsgItem.setEnabled(true);
rcvMsgItem.setEnabled(true);
connDialogB.setVisible(false);
setClientID();
setFooter("Connected to " + getHostName() + ":" + getPort());
setHostPort(getHostName() + ":" + getPort());
}
/**
* creates the actual connection a broker
*/
private boolean createConnection() {
try {
setHostName(connDialogB.getHost());
setPort(connDialogB.getPort());
//this is required in case the MQ client runtime is trying to do a auto reconnect
if (myConn != null) {
myConn.close();
}
myConnFactory = new com.sun.messaging.ConnectionFactory();
Properties props = getConnFactoryConfig();
UniversalClientUtility.setConnFactoryProperties((com.sun.messaging.ConnectionFactory) myConnFactory,
props);
((com.sun.messaging.ConnectionFactory) myConnFactory).setProperty(com.sun.messaging.ConnectionConfiguration.imqBrokerHostName,
getHostName());
((com.sun.messaging.ConnectionFactory) myConnFactory).setProperty(com.sun.messaging.ConnectionConfiguration.imqBrokerHostPort,
String.valueOf(getPort()));
((com.sun.messaging.ConnectionFactory) myConnFactory).setProperty(com.sun.messaging.ConnectionConfiguration.imqConfiguredClientID,
String.valueOf(getClientID()));
myConn = myConnFactory.createConnection(getUserName(), getPassword());
//construct a MQ event listener, the listener implements com.sun.messaging.jms.notification.EventListener interface.
com.sun.messaging.jms.notification.EventListener eListener = new ConnectionEventListener();
//set event listener to the MQ connection.
((com.sun.messaging.jms.Connection) myConn).setEventListener(eListener);
myConn.setExceptionListener(this);
myConn.start();
return true;
} catch (Exception e) {
errorMessage("Caught Exception: " + e);
showErrorDialog(e, "Connection Error");
//e.printStackTrace();
return false;
}
}
/**
* responsible for creating and sending message when one clicks on the
* send message button of Send Message dialog box. If a Message Producer does not
* exist for a given destination creates a new one for sending messages.
*/
private void doSendMessage() {
if (!connected()) {
errorMessage("Unable to send Message. " +
"Please verify a broker is running");
return;
}
sendMsgDialogB.setVisible(false);
try {
boolean isTransacted = sendMsgDialogB.isTransacted();
int destType = sendMsgDialogB.getDestinationType();
String destName = sendMsgDialogB.getDestinationName();
myProducerSession = getProducerSession(isTransacted);
myDestination = createDestination(destType, destName,
myProducerSession);
myProducer = getProducer(myDestination, isTransacted);
if (sendMsgDialogB.getDeliveryMode() == DELIVERY_MODE_NON_PERSISTENT) {
myProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
}
//start a message sender thread
Thread msgSender = new MessageSenderThread();
msgSender.start();
} catch (Exception e) {
errorMessage("Unable to send message:" + e.getMessage());
showErrorDialog(e, "Create Destination Error");
doDisconnect();
}
}
/**
* get Message Consumer for a given destination topic or queue
*/
private MessageConsumer getConsumer(Destination dest, int destType,
boolean isTransacted, Session s, String selector)
throws JMSException {
MessageConsumer c = null;
if (destType == DESTINATION_TYPE_TOPIC_DURABLE) {
myConn.stop();
c = s.createDurableSubscriber((Topic) dest, getClientID(),
selector, false);
myConn.start();
} else {
c = s.createConsumer(dest, selector);
}
return c;
}
/**
* get Message Producer for a given destination if one exist or create a new Producer
*/
private MessageProducer getProducer(Destination dest, boolean isTransacted)
throws JMSException {
String key = dest.toString() + isTransacted;
MessageProducer p = (MessageProducer) myProducerMap.get(key);
if (p == null) {
p = myProducerSession.createProducer(dest);
myProducerMap.put(key, p);
}
return p;
}
/**
* get JMS Session for producer depending on whether it is transacted or not
*/
private Session getProducerSession(boolean isTransacted)
throws JMSException {
String key = new String("session" + isTransacted) + "Producer";
Session s = (Session) mySessionMap.get(key);
if (s == null) {
s = myConn.createSession(isTransacted, Session.AUTO_ACKNOWLEDGE);
mySessionMap.put(key, s);
}
return s;
}
/**
* get JMS Session for consumer depending on whether it is transacted or not
*/
private Session getConsumerSession(boolean isTransacted, int ackMode)
throws JMSException {
String key = new String("session" + isTransacted) + "Consumer" +
ackMode;
Session s = (Session) mySessionMap.get(key);
if (s == null) {
if (ackMode == AUTO_ACKNOWLEDGE) {
ackMode = Session.AUTO_ACKNOWLEDGE;
} else if (ackMode == CLIENT_ACKNOWLEDGE) {
ackMode = Session.CLIENT_ACKNOWLEDGE;
} else if (ackMode == DUPS_OK_ACKNOWLEDGE) {
ackMode = Session.DUPS_OK_ACKNOWLEDGE;
}
//note: If a Session is transacted, the acknowledgement mode is ignored.
s = myConn.createSession(isTransacted, ackMode);
mySessionMap.put(key, s);
}
return s;
}
/**
* sends n # of messages
* this method is called from a message sender thread
*/
private void sendMessage() {
boolean isTransacted = sendMsgDialogB.isTransacted();
int numOfMsg = sendMsgDialogB.getNumOfMsg();
int delayBetweenMsg = sendMsgDialogB.getDelayBetweenMsg();
sendMsgItem.setEnabled(false);
sendMsgStopItem.setEnabled(true);
setMsgSenderStopped(false);
sendMsgProgressBar.setMaximum(numOfMsg);
String msgStr = null;
long t1 = System.currentTimeMillis();
int msgIndex = 0;
for (; msgIndex < numOfMsg; msgIndex++) {
Message msg = null;
if (isMsgSenderStopped()) {
break;
}
try {
try {
msg = createMessage(msgIndex + 1, numOfMsg);
myProducer.send(msg);
if (isTransacted) {
myProducerSession.rumit();
}
} catch (TransactionRolledBackException e) {
msgIndex--;
} catch (JMSException e) {
if (isTransacted) {
myProducerSession.rollback();
msgIndex--;
continue;
}
}
} catch (Exception e) {
showErrorDialog(e, "Send Message Error");
e.printStackTrace();
if (isValidConnection()) {
sendMsgItem.setEnabled(true);
}
sendMsgStopItem.setEnabled(false);
setMsgSenderStopped(false);
setSendMsgProgressBar(0, "");
return;
}
try {
msgStr = "Sending Message " + (msgIndex + 1) + " of " +
numOfMsg + " To " +
UniversalClientUtility.getDestination(msg);
} catch (JMSException e1) {
e1.printStackTrace();
}
setSendMsgProgressBar(msgIndex, msgStr);
if (!(delayBetweenMsg == 0)) {
try {
Thread.sleep(delayBetweenMsg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
long t2 = System.currentTimeMillis();
msgProductionRate = (msgIndex * 1000.00) / (t2 - t1);
setMsgProductionRate(new Double(msgProductionRate));
if (isMsgSenderStopped()) {
setSendMsgProgressBar(msgIndex, "Sending Message Stopped ....");
} else {
setSendMsgProgressBar(msgIndex, "Sending Message Completed ....");
}
if (connected()) {
sendMsgItem.setEnabled(true);
} else {
setMsgProductionRate(new String("N/A"));
}
sendMsgStopItem.setEnabled(false);
setMsgSenderStopped(false);
//let the user see the status for 2 sec
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setSendMsgProgressBar(0, "");
}
/**
* constructs message of given type, size and ttl
*/
public Message createMessage(int msgNum, int totalNumMsgs)
throws Exception {
int ttl = sendMsgDialogB.getMsgTTL();
int type = sendMsgDialogB.getMsgType();
int size = sendMsgDialogB.getMsgSize();
boolean compressed = (sendMsgDialogB.getCompression() == MSG_COMPRESSED);
Message msg = null;
byte b = "s";
byte[] byteArr = new byte[size];
Arrays.fill(byteArr, b);
switch (type) {
case MSG_TYPE_TEXT:
msg = myProducerSession.createTextMessage();
((TextMessage) msg).setText(new String(byteArr));
break;
case MSG_TYPE_OBJECT:
msg = myProducerSession.createObjectMessage();
((ObjectMessage) msg).setObject(new String(byteArr));
break;
case MSG_TYPE_MAP:
msg = myProducerSession.createMapMessage();
((MapMessage) msg).setString("hello", new String(byteArr));
break;
case MSG_TYPE_BYTES:
msg = myProducerSession.createBytesMessage();
((BytesMessage) msg).writeBytes(byteArr);
break;
case MSG_TYPE_STREAM:
msg = myProducerSession.createStreamMessage();
((StreamMessage) msg).writeBytes(byteArr);
break;
}
msg.setJMSExpiration(ttl);
msg.setJMSType("Universal Client");
msg.setIntProperty("totalNumMsgs", totalNumMsgs);
msg.setIntProperty("msgNum", msgNum);
msg.setStringProperty("msgNumStr", String.valueOf(msgNum));
msg.setStringProperty("msgSource", "I am coming from universal client");
msg.setBooleanProperty("JMS_SUN_COMPRESS", compressed);
return (msg);
}
/**
* create destination Topic or Queue for a given session
*/
private Destination createDestination(int type, String name, Session s)
throws JMSException {
Destination dest = null;
if (type == DESTINATION_TYPE_QUEUE) {
dest = s.createQueue(name);
} else {
dest = s.createTopic(name);
}
return dest;
}
/**
* @return Returns the password.
*/
public String getPassword() {
return connDialogB.getPassword();
}
/**
* @return Returns connection factory configuration
*/
public Properties getConnFactoryConfig() {
return connDialogB.getConfiguration();
}
/**
* @return Returns the userName.
*/
public String getUserName() {
return connDialogB.getPassword();
}
/**
* @return Returns the hostName.
*/
public String getHostName() {
return hostName; //connDialogB.getHost();
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
/**
* @return Returns the port.
*/
public int getPort() {
return port; //connDialogB.getPort();
}
public void setPort(int port) {
this.port = port;
}
/**
* @return Returns the clientID.
*/
public String getClientID() {
if (connDialogB == null) {
return clientID;
} else {
return connDialogB.getClientID();
}
}
/**
* creates a consumer and start the message receiver thread
* for receiving messages for a given destination
*/
private void doReceiveMessage() {
if (!connected()) {
errorMessage("Unable to send Message. " +
"Please verify a broker is running");
return;
}
receiveMsgDialogB.setVisible(false);
try {
boolean isTransacted = receiveMsgDialogB.isTransacted();
String destName = receiveMsgDialogB.getDestinationName();
int destType = receiveMsgDialogB.getDestinationType();
String selector = receiveMsgDialogB.getSelector();
int ackMode = receiveMsgDialogB.getAcknowledgeMode();
myConsumerSession = getConsumerSession(isTransacted, ackMode);
myDestination = createDestination(destType, destName,
myConsumerSession);
myConsumer = getConsumer(myDestination, destType, isTransacted,
myConsumerSession, selector);
//start message receiver thread
Thread msgReceiver = new MessageReceiverThread();
msgReceiver.start();
} catch (ResourceAllocationException rae) {
showErrorDialog(rae, "Receive Message Error");
} catch (Exception e) {
showErrorDialog(e, "Receive Message Error");
doDisconnect();
}
}
private boolean isValidConnection() {
boolean result = false;
if (myConn == null) {
return false;
} else {
try {
myConn.start();
result = true;
} catch (JMSException e) {
e.printStackTrace();
}
}
return result;
}
/**
* receives message for a consumer, blocks on a receive call, if
* consumer is closed , the method returns
* this method is called from a message receiver thread
*/
private void receiveMessage() {
int counter = 0;
boolean isTransacted = receiveMsgDialogB.isTransacted();
int ackMode = receiveMsgDialogB.getAcknowledgeMode();
int delayBetweenMsg = receiveMsgDialogB.getDelayBetweenMsg();
rcvMsgItem.setEnabled(false);
rcvMsgStopItem.setEnabled(true);
setFooterInUse(true);
setFooter("Waiting on a message Receive() call");
try {
while (true) {
Message msg = null;
try {
msg = myConsumer.receive();
if (msg == null) {
//reset the stop flag for msg receiver
setMsgReceiverStopped(false);
break;
}
if (isTransacted) {
myConsumerSession.rumit();
} else {
if (ackMode == CLIENT_ACKNOWLEDGE) {
msg.acknowledge();
}
}
} catch (TransactionRolledBackException ex) {
if (isMsgReceiverStopped()) {
//reset the stop flag for msg receiver
setMsgReceiverStopped(false);
break;
}
if (isValidConnection()) {
continue;
} else {
break;
}
} catch (JMSException ex) {
if (isTransacted) {
myConsumerSession.rollback();
}
if (isMsgReceiverStopped()) {
//reset the stop flag for msg receiver
setMsgReceiverStopped(false);
break;
}
if (isValidConnection()) {
continue;
} else {
break;
}
}
counter++;
addMessageToTable(msg);
try {
String msgStr = "Last Received Message # " +
msg.getIntProperty("msgNum") + "/" +
msg.getIntProperty("totalNumMsgs") + " From " +
UniversalClientUtility.getDestination(msg);
setFooter(msgStr);
} catch (JMSException e) {
e.printStackTrace();
}
if (!(delayBetweenMsg == 0)) {
try {
Thread.sleep(delayBetweenMsg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
myConsumer.close();
} catch (Exception e) {
showErrorDialog(e, "Receive Message Error");
setFooterInUse(false);
return;
}
rcvMsgItem.setEnabled(true);
rcvMsgStopItem.setEnabled(false);
String counterStr = (counter == 0) ? "NONE"
: (new Integer(counter).toString());
setFooter("Received messages for this transaction: " + counterStr);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setFooterInUse(false);
}
/**
* shows status of message table
* this method is called from status reporting thread
*/
public void showCurrentStatus() {
MsgTable mt = (MsgTable) msgTable.getModel();
int n = mt.getRowCount();
if (isFooterInUse()) {
frame.repaint();
}
if ((n != 0) && !isFooterInUse()) {
setFooter("Message Table Current Size " + ": " + String.valueOf(n));
}
}
/**
* when auto-scrolling is enabled this is used to
* scroll to last row of message table
*/
public void scrollToLastRowOfTable() {
Rectangle rect = UniversalClientUtility.getRowBounds(msgTable,
msgTable.getRowCount() - 1);
msgTable.scrollRectToVisible(rect);
}
/**
* add received message on to message table
*/
public void addMessageToTable(Message msg) {
MsgTable mt = (MsgTable) msgTable.getModel();
int n = 0;
try {
n = mt.addMessage(msg);
if (n > MAX_TABLE_SIZE) {
throw new ArrayIndexOutOfBoundsException();
}
if (isScrollingON()) {
scrollToLastRowOfTable();
}
mt.updateUI();
} catch (Exception e) {
showErrorDialog("Exceeded MAX Table Capacity: " +
"All Messages will be deleted", "Message Loading Error");
mt.clearData();
}
}
/**
* Disconnects from session. destroyCurrentSession() performs the JMS
* cleanup.
*/
private void doDisconnect() {
if (!connected()) {
return;
}
destroyCurrentSession();
setConnected(false);
connectItem.setEnabled(true);
disconnectItem.setEnabled(false);
sendMsgItem.setEnabled(false);
sendMsgStopItem.setEnabled(false);
rcvMsgItem.setEnabled(false);
rcvMsgStopItem.setEnabled(false);
setFooter("Not Connected");
setClientID();
setHostPort("Not Connected");
setMsgProductionRate("Not Available");
}
/**
* Destroy/close " Current session"
* and clean all data structures
*/
private void destroyCurrentSession() {
try {
//close consumer
if (myConsumer != null) {
myConsumer.close();
}
//close all producers
Iterator iterator = myProducerMap.values().iterator();
while (iterator.hasNext()) {
MessageProducer element = (MessageProducer) iterator.next();
element.close();
}
myProducerMap.clear();
//close all producer & consumer session
iterator = mySessionMap.values().iterator();
while (iterator.hasNext()) {
Session element = (Session) iterator.next();
element.close();
}
mySessionMap.clear();
clearMessageList();
//close connection
//myConn.close();
//myConsumer = null;myProducer = null;myProducerSession = null;myConsumerSession = null;myConn = null;
} catch (Exception e) {
errorMessage("Caught Exception: " + e);
myProducerMap.clear();
mySessionMap.clear();
clearMessageList();
//e.printStackTrace();
}
}
/**
* clears all existing messages from message table
*/
private void clearMessageList() {
MsgTable mt = (MsgTable) msgTable.getModel();
mt.clearData();
setFooter("Message List Cleared");
}
/**
* Display error:display it in the footer panel
*/
private void errorMessage(String s) {
setFooter(s);
}
/**
* shows information message in a dialog box for String
*/
private void showInformationDialog(String s, String reason) {
JOptionPane.showMessageDialog(frame, s, reason,
JOptionPane.INFORMATION_MESSAGE);
}
/**
* shows error message in a dialog box for String
*/
private void showErrorDialog(String s, String reason) {
JOptionPane.showMessageDialog(frame, s, reason,
JOptionPane.ERROR_MESSAGE);
}
/**
* shows error message in a dialog box for Exception
*/
private void showErrorDialog(Exception e, String reason) {
JOptionPane.showMessageDialog(frame, e, reason,
JOptionPane.ERROR_MESSAGE);
}
/**
* These methods set a flag that indicates whether the application is
* currently involved in a jms session.
*/
private void setConnected(boolean b) {
connected = b;
}
/**
* These methods return a flag that indicates whether the application is
* currently involved in a jms session.
*/
private boolean connected() {
return (connected);
}
/**
* Exit application. Does some cleanup if necessary.
*/
private void exit() {
doDisconnect();
System.exit(0);
}
/**
* create footer panel
*/
private JPanel createFooterPanel() {
footerPanel = new JPanel();
footerPanel.setLayout(new BorderLayout());
footerLabel = new JLabel("");
footerPanel.add(BorderLayout.WEST, footerLabel);
JPanel dummyP = new JPanel();
JButton details = new JButton("Message Details");
details.setToolTipText("Show Message Details ");
details.addActionListener(new DetailsListener());
footerPanel.setBorder(BorderFactory.createEtchedBorder(
EtchedBorder.RAISED));
//can add other items if required
dummyP.add(details);
footerPanel.add(BorderLayout.EAST, dummyP);
return footerPanel;
}
/**
* @return Returns the scrollingON.
*/
public boolean isScrollingON() {
return scrollingON;
}
/**
* @param scrollingON The scrollingON to set.
*/
public void setScrollingON(boolean scrollingON) {
this.scrollingON = scrollingON;
}
/**
* @return Returns the footerInUse.
*/
public boolean isFooterInUse() {
return footerInUse;
}
/**
* @param footerInUse The footerInUse to set.
*/
public void setFooterInUse(boolean footerInUse) {
this.footerInUse = footerInUse;
}
/**
* Set text on footer
*/
private void setFooter(String s) {
footerLabel.setText(s);
footerLabel.repaint();
}
/**
* set text Client ID label
*/
private void setClientID() {
if (connected()) {
clientIDLabel.setText("Client ID: " + getClientID());
} else {
clientIDLabel.setText("Client ID: " + clientID);
}
clientIDLabel.paintImmediately(clientIDLabel.getBounds());
}
/**
* Set text for host:port
*/
private void setHostPort(String hostPort) {
hostPortLabel.setText("Hostname & Port: " + hostPort);
hostPortLabel.paintImmediately(hostPortLabel.getBounds());
}
/**
* Set value and string for SendMsgProgressBar
*/
private void setSendMsgProgressBar(int value, String msgStr) {
sendMsgProgressBar.setValue(value);
sendMsgProgressBar.setString(msgStr);
sendMsgProgressBar.setStringPainted(true);
}
/**
* Set text for msg production rate
*/
private void setMsgProductionRate(Object rate) {
String r = null;
if (rate instanceof Double) {
r = rate + " (msg/sec)";
} else {
r = rate.toString();
}
msgProductionRateLabel.setText("Msg Production Rate: " + r);
msgProductionRateLabel.paintImmediately(msgProductionRateLabel.getBounds());
}
/**
* Show the contents of a message in a seperate popup window
*/
private void showDetails(Message msg, int msgno) {
try {
msgno = msg.getIntProperty("msgNum");
} catch (JMSException e) {
e.printStackTrace();
}
if (detailsFrame == null) {
// Create popup
detailsFrame = new JFrame();
detailsFrame.setTitle(title + " - Message Details");
detailsFrame.setBackground(Color.white);
detailsFrame.getContentPane().setLayout(new BorderLayout());
msgDetailsHeaderPanel = new PropertyPanel();
msgDetailsHeaderPanel.setTitle("JMS Headers");
detailsFrame.getContentPane().add(BorderLayout.NORTH,
msgDetailsHeaderPanel);
msgDetailsPropertyPanel = new PropertyPanel();
msgDetailsPropertyPanel.setTitle("Message Properties");
detailsFrame.getContentPane().add(BorderLayout.CENTER,
msgDetailsPropertyPanel);
msgDetailsBodyPanel = new PropertyPanel();
msgDetailsBodyPanel.setTitle("Message body");
detailsFrame.getContentPane().add(BorderLayout.SOUTH,
msgDetailsBodyPanel);
detailsFrame.pack();
}
// Load JMS headers from message
try {
HashMap hdrs = UniversalClientUtility.jmsHeadersToHashMap(msg);
msgDetailsHeaderPanel.setTitle("JMS Headers: Message #" + msgno);
msgDetailsHeaderPanel.load(hdrs);
} catch (JMSException ex) {
setFooter("Error: " + ex.getMessage());
}
// Load message properties
HashMap props = new HashMap();
// Get all message properties and stuff into a hash table
try {
for (Enumeration enu = msg.getPropertyNames();
enu.hasMoreElements();) {
String name = (enu.nextElement()).toString();
props.put(name, (msg.getObjectProperty(name)).toString());
}
} catch (JMSException ex) {
setFooter("Error: " + ex.getMessage());
}
msgDetailsPropertyPanel.load(props);
// Load message body
msgDetailsBodyPanel.setTitle("Message Body: (" +
UniversalClientUtility.messageType(msg) + ")");
msgDetailsBodyPanel.load(UniversalClientUtility.jmsMsgBodyAsString(msg));
detailsFrame.setVisible(true);
}
/**
* handles notification event "ConnectionReconnectedEvent"
* when MQ client run time is able to recover a connection
*/
public void handleAutoReconnect(
com.sun.messaging.jms.notification.Event connEvent) {
String eventMessage = connEvent.getEventMessage();
StringTokenizer st = new StringTokenizer(eventMessage, ":");
st.nextToken(); //event code
st.nextToken(); //event message
//TODO to replace the code with something safer
String host = st.nextToken();
String portStr = st.nextToken();
portStr = portStr.substring(0, portStr.indexOf("("));
//set host and port, to be displayed by UI
setHostName(host);
setPort(Integer.parseInt(portStr));
setUpUIAfterConnection();
showInformationDialog(connEvent.getEventMessage(),
"Auto Reconnect Successful");
}
/**
* handles notification events related to connection
* which are emitted by MQ client run time
*/
public void onException(JMSException ex) {
// handle ConnectionClosedEvent or ConectionClosingEvent or ConnectionExitEvent
setMsgSenderStopped(true);
// note the message receiver thread exits when the connection is closed/exit
// so no need to close the message consumer
doDisconnect();
showErrorDialog(ex.toString(), "Connection Closing Event");
}
/**
* @return Returns the msgSenderStopped.
*/
public boolean isMsgSenderStopped() {
return msgSenderStopped;
}
/**
* @param msgSenderStopped The msgSenderStopped to set.
*/
public void setMsgSenderStopped(boolean msgSenderStopped) {
this.msgSenderStopped = msgSenderStopped;
}
/**
* stop the message consmer
*/
public void stopMsgReceiver() {
if (myConsumer != null) {
try {
setMsgReceiverStopped(true);
myConsumer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* appends to status area
*/
public void printToStatusArea(String message) {
statusArea.appendText("[" + new Date() + "] " + message);
}
public boolean isMsgReceiverStopped() {
return msgReceiverStopped;
}
public void setMsgReceiverStopped(boolean msgReceiverStopped) {
this.msgReceiverStopped = msgReceiverStopped;
}
/**
* the uclient application exits
*/
class ExitListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
exit();
}
}
/**
* clears all existing message of the message table
*/
class ClearMessageListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
clearMessageList();
}
}
/**
* pops up Connection dialog box
*/
class ConnectionPopUpListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
popUpConnDialogBox();
}
}
/**
* pops up Send message dialog box
*/
class SendMessagePopUpListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
popUpSendMessageDialogBox();
}
}
/**
* pops up Receive message dialog box
*/
class ReceiveMessagePopUpListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
popUpReceiveMessageDialogBox();
}
}
/**
* connects to broker when the "Connect" button of
* connection dialog box is clicked
*/
class ConnectionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
doConnect();
}
}
/**
* Handles the notification events emitted by MQ client runtime
* This events could be due to BROKER shutdown, restart, error, crash
* or MQ client runtime reconnect succesful or reconnect failed
*/
class ConnectionEventListener
implements com.sun.messaging.jms.notification.EventListener {
public void onEvent(com.sun.messaging.jms.notification.Event connEvent) {
log(connEvent);
if (connEvent instanceof ConnectionReconnectedEvent) {
String brokerAddr = ((ConnectionReconnectedEvent) connEvent).getBrokerAddress();
// Broker address is in the format IP_address:port(actual_port);
// we just want the IP_address:port part of the address.
int index = brokerAddr.indexOf("(");
if (index > 0) {
brokerAddr = brokerAddr.substring(0, index);
}
setHostPort(brokerAddr);
}
}
private void log(com.sun.messaging.jms.notification.Event connEvent) {
//String eventCode = connEvent.getEventCode();
String eventMessage = connEvent.getEventMessage();
printToStatusArea(eventMessage);
}
}
/**
* dis connects client connection when user clicks on
* "DisConnect" Menu Item
*/
class DisConnectionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
doDisconnect();
try {
//close connection only when the user wants to close
myConn.close();
} catch (JMSException e1) {
e1.printStackTrace();
}
printToStatusArea("Successfully Disconnected from " +
getHostName() + ":" + getPort());
}
}
/**
* starts sending message once the "send" button of
* send msg dialog box is clicked
*/
class SendMessageListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
doSendMessage();
}
}
/**
* starts receiving message once "receive" button of
* receive msg dialog box is clicked
*/
class ReceiveMessageListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
doReceiveMessage();
}
}
/**
* shows message details when message table row is double clicked
*/
class TableMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int row = msgTable.getSelectedRow();
MsgTable mt = (MsgTable) msgTable.getModel();
Message msg = mt.getMessageAtRow(row);
showDetails(msg, row);
}
}
}
/**
* shows message details when message details button is clicked
*/
class DetailsListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
int row = msgTable.getSelectedRow();
if (row < 0) {
setFooter("Please select a message");
return;
}
MsgTable mt = (MsgTable) msgTable.getModel();
Message msg = mt.getMessageAtRow(row);
showDetails(msg, row);
}
}
/**
* this thread is responsible for sending messages
*/
class MessageSenderThread extends Thread {
public void run() {
sendMessage();
}
}
/**
* this thread is responsible for receiving messages
*/
class MessageReceiverThread extends Thread {
public void run() {
receiveMessage();
}
}
/**
* StatusReporting thread is responsible for showing the message table status
* also refreshes the main frame when the client receives messages
*/
class StatusReportingThread extends Thread {
public void run() {
while (true) {
if (connected()) {
showCurrentStatus();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* Dialog for connecting to broker, user name and password.
*
*/
class ConnectionDialogBox extends JDialog {
private static final long serialVersionUID = 3544395815952070704L;
private JTextField userNameF;
private JPasswordField passwordF;
private JButton connectB;
private JButton cancelB;
private JComboBox hostPortComboBox;
private JTextField clientIDF;
private String host;
private int port;
private JTextArea cfTextArea;
//
JPanel p = new JPanel(new BorderLayout());
JPanel dummyPanel = new JPanel();
JPanel valuePanel = new JPanel();
GridBagLayout valueGbag = new GridBagLayout();
GridBagConstraints valueConstraints = new GridBagConstraints();
/**
* @param f
*/
public ConnectionDialogBox(JFrame f) {
super(f, "Universal Client: Connection information", true);
init();
setResizable(false);
setLocationRelativeTo(f);
}
/**
* Init GUI elements.
*/
private void init() {
int y = 0;
valuePanel.setLayout(valueGbag);
hostPortComboBox = new JComboBox();
Dimension d = hostPortComboBox.getPreferredSize();
d.setSize(8 * d.getWidth(), d.getHeight());
hostPortComboBox.setPreferredSize(d);
hostPortComboBox.setEditable(true);
addDestToMenu("localhost:7676");
addLabelAndValueComponent("Host:Port: ", hostPortComboBox, y++);
userNameF = new JTextField(24);
addLabelAndValueComponent("User Name: ", userNameF, y++);
passwordF = new JPasswordField(24);
addLabelAndValueComponent("Password: ", passwordF, y++);
clientIDF = new JTextField(24);
addLabelAndValueComponent("Client ID: ", clientIDF, y++);
dummyPanel.add("Center", valuePanel);
p.add("North", dummyPanel);
//p.setBackground(Color.GRAY);
p.setBorder(BorderFactory.createEtchedBorder());
dummyPanel = new JPanel();
connectB = new JButton("Connect");
cancelB = new JButton("Cancel");
dummyPanel.add(connectB);
dummyPanel.add(cancelB);
p.add("South", dummyPanel);
cfTextArea = new JTextArea();
cfTextArea.setFont(new Font("DialogInput", Font.BOLD, 11));
//cfTextArea.setLineWrap(true);
cfTextArea.setWrapStyleWord(true);
cfTextArea.setEditable(true);
JScrollPane areaScrollPane = new JScrollPane(cfTextArea);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(350, 150));
String connFactoryAttributes = "" +
"# Edit/Change default attribute values if required \n\n" +
"# Connection Handling \n" + "imqAddressList= \n" +
"imqAddressListBehavior=PRIORITY \n" +
"imqAddressListIterations=1 \n" + "imqReconnectEnabled = false \n" +
"imqReconnectAttempts = 0 \n" + "imqReconnectInterval=3000 \n" +
" \n" + "# Connection handling attribute \n" +
"imqConnectionType=TCP \n" + "imqSSLIsHostTrusted=true \n" +
"imqConnectionURL=http://localhost/imq/tunnel \n" +
"imqBrokerServicePort=0 \n" + " \n" + "# Client Identification \n" +
"imqDefaultUsername=guest \n" + "imqDefaultPassword=guest \n" +
"imqDisableSetClientID=false \n" + " \n" +
"# Message Header Overrides \n" +
"imqOverrideJMSDeliveryMode=false \n" + "imqJMSDeliveryMode=2 \n" +
"imqOverrideJMSExpiration=false \n" + "imqJMSExpiration=0 \n" +
"imqOverrideJMSPriority=false \n" + "imqJMSPriority=4 \n" +
"imqOverrideJMSHeadersToTemporaryDestinations=false \n" + " \n" +
"# Reliability and Flow Control \n" + "imqAckTimeout=0 \n" +
"imqAckOnProduce= \n" + "imqAckOnAcknowledge= \n" +
"imqConnectionFlowCount=100 \n" +
"imqConnectionFlowLimitEnabled=false \n" +
"imqConnectionFlowLimit=1000 \n" + "imqConsumerFlowLimit=100 \n" +
"imqConsumerFlowThreshold=50 \n" + " \n" +
"# Queue Browser Behavior \n" +
"imqQueueBrowserMaxMessagesPerRetrieve=1000 \n" +
"imqQueueBrowserRetrieveTimeout=60000 \n" +
"imqLoadMaxToServerSession=true \n" + " \n" +
"# JMS-defined Properties Support \n" +
"imqSetJMSXUserID=false \n" + "imqSetJMSXAppID=false \n" +
"imqSetJMSXProducerTXID=false \n" +
"imqSetJMSXConsumerTXID=false \n" +
"imqSetJMSXRcvTimestamp=false \n" + " \n" + "";
cfTextArea.setText(connFactoryAttributes);
cfTextArea.setCaretPosition(0);
dummyPanel = new JPanel(new BorderLayout());
dummyPanel.add("North", new JLabel("Connection Factory Attributes"));
dummyPanel.add("South", areaScrollPane);
dummyPanel.setBorder(BorderFactory.createEtchedBorder());
p.add("Center", dummyPanel);
getContentPane().add(p);
pack();
}
private void addLabelAndValueComponent(String labelStr, Component value,
int yAxis) {
JLabel label = new JLabel(labelStr, Label.RIGHT);
valueConstraints.gridx = 0;
valueConstraints.gridy = yAxis;
valueConstraints.weightx = 1.0;
valueConstraints.weighty = 1.0;
valueConstraints.anchor = GridBagConstraints.WEST;
valueGbag.setConstraints(label, valueConstraints);
valuePanel.add(label);
valueConstraints.gridx = 1;
valueConstraints.gridy = yAxis;
valueConstraints.weightx = 1.0;
valueConstraints.weighty = 1.0;
valueConstraints.anchor = GridBagConstraints.WEST;
valueGbag.setConstraints(value, valueConstraints);
valuePanel.add(value);
}
/**
* Add a name to the "Queue Name" combo box menu
*/
private void addDestToMenu(String name) {
DefaultComboBoxModel model = (DefaultComboBoxModel) hostPortComboBox.getModel();
if (model.getIndexOf(name) < 0) {
// Name is not in menu. Add it.
model.addElement(name);
}
}
/**
* Return "Connect" button
*/
public JButton getConnectButton() {
return (connectB);
}
/**
* Return "Cancel" button
*/
public JButton getCancelButton() {
return (cancelB);
}
/**
* Return user name entered.
*/
public String getUserName() {
if (userNameF == null) {
return (null);
}
return (userNameF.getText());
}
/**
* Set chat user name.
*/
public void setUserName(String s) {
if (userNameF == null) {
return;
}
userNameF.setText(s);
}
/**
* Return user password entered.
*/
public String getPassword() {
if (passwordF == null) {
return (null);
}
return (new String(passwordF.getPassword()));
}
/**
* Set password.
*/
public void setPassword(String s) {
if (passwordF == null) {
return;
}
passwordF.setText(s);
}
/**
* @return Returns the host.
*/
public String getHost() {
String hostPort = (String) hostPortComboBox.getEditor().getItem();
host = hostPort.substring(0, hostPort.indexOf(":")).trim();
return host;
}
/**
* @param host The host to set.
*/
public void setHost(String host) {
this.host = host;
}
/**
* @return Returns the port.
*/
public int getPort() {
String hostPort = (String) hostPortComboBox.getEditor().getItem();
String portStr = hostPort.substring(hostPort.indexOf(":") + 1);
port = new Integer(portStr.trim()).intValue();
return port;
}
/**
* @param port The port to set.
*/
public void setPort(int port) {
this.port = port;
}
/**
* @return Returns the clientID.
*/
public String getClientID() {
if (clientIDF != null) {
return clientIDF.getText();
}
return null;
}
/**
* @param clientID The clientID to set.
*/
public void setClientID(String clientID) {
if (clientIDF != null) {
clientIDF.setText(clientID);
}
}
/**
* get configuration for connection factory
*/
public Properties getConfiguration() {
Properties props = new Properties();
try {
props.load(new ByteArrayInputStream(cfTextArea.getText().getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
return props;
}
}
/**
* Dialog for sending one or more message, for a given destination Topic or Queue
*/
class SendMessageDialogBox extends JDialog implements UniversalClientConstants {
private static final long serialVersionUID = 3258132444711302966L;
private JTextField destinationNameF = new JTextField("defaultDest", 15);
private JComboBox destinationType = new JComboBox();
private JComboBox msgType = new JComboBox();
private IntegerField msgSize = new IntegerField(10, 15);
private IntegerField msgTTL = new IntegerField(10, 15);
private JComboBox transactionType = new JComboBox();
private JComboBox deliveryMode = new JComboBox();
private JComboBox compression = new JComboBox();
private IntegerField numOfMsg = new IntegerField(300, 15);
private IntegerField delayBetweenMsg = new IntegerField(1000, 15);
// buttons
private JButton sendButton = new JButton("Send Message");
private JButton cancelButton = new JButton("Cancel");
//
JPanel p = new JPanel(new BorderLayout());
JPanel dummyPanel = new JPanel();
JPanel valuePanel = new JPanel();
GridBagLayout valueGbag = new GridBagLayout();
GridBagConstraints valueConstraints = new GridBagConstraints();
/**
* @param owner
*/
public SendMessageDialogBox(Frame owner) {
super(owner, "Universal Client: Send Message", true);
init();
setResizable(false);
setLocationRelativeTo(owner);
}
private void init() {
int y = 0;
valuePanel.setLayout(valueGbag);
addLabelAndValueComponent("Destination Name", destinationNameF, y++);
destinationType.insertItemAt("Queue ", DESTINATION_TYPE_QUEUE);
destinationType.insertItemAt("Topic", DESTINATION_TYPE_TOPIC);
destinationType.setSelectedIndex(DESTINATION_TYPE_QUEUE);
addLabelAndValueComponent("Destination Type", destinationType, y++);
addLabelAndValueComponent("Message Size (bytes)", msgSize, y++);
addLabelAndValueComponent("Message TTL (sec)", msgTTL, y++);
deliveryMode.insertItemAt("PERSISTENT", DELIVERY_MODE_PERSISTENT);
deliveryMode.insertItemAt("NON PERSISTENT", DELIVERY_MODE_NON_PERSISTENT);
deliveryMode.setSelectedIndex(DELIVERY_MODE_PERSISTENT);
addLabelAndValueComponent("Delivery Mode", deliveryMode, y++);
transactionType.insertItemAt("Session Transacted", SESSION_TRANSACTED);
transactionType.insertItemAt("Session Non Transacted",
SESSION_NON_TRANSACTED);
transactionType.setSelectedIndex(SESSION_TRANSACTED);
addLabelAndValueComponent("Transaction Type", transactionType, y++);
compression.insertItemAt("Compressed", MSG_COMPRESSED);
compression.insertItemAt("Non Compressed", MSG_NON_COMPRESSED);
compression.setSelectedIndex(MSG_NON_COMPRESSED);
addLabelAndValueComponent("Compression Type", compression, y++);
msgType.insertItemAt("ObjectMessage", MSG_TYPE_OBJECT);
msgType.insertItemAt("TextMessage", MSG_TYPE_TEXT);
msgType.insertItemAt("MapMessage", MSG_TYPE_MAP);
msgType.insertItemAt("BytesMessage", MSG_TYPE_BYTES);
msgType.insertItemAt("StreamMessage", MSG_TYPE_STREAM);
msgType.setSelectedIndex(MSG_TYPE_TEXT);
addLabelAndValueComponent("Message Type:", msgType, y++);
addLabelAndValueComponent("Number of Message", numOfMsg, y++);
addLabelAndValueComponent("Delay Between Msg(ms)", delayBetweenMsg, y++);
//use a dummy panel
dummyPanel.add("Center", valuePanel);
p.add("North", dummyPanel);
//p.setBackground(Color.GRAY);
p.setBorder(BorderFactory.createEtchedBorder());
dummyPanel = new JPanel();
dummyPanel.add(sendButton);
dummyPanel.add(cancelButton);
p.add("South", dummyPanel);
getContentPane().add(p);
pack();
}
private void addLabelAndValueComponent(String labelStr, Component value,
int yAxis) {
JLabel label = new JLabel(labelStr, Label.RIGHT);
valueConstraints.gridx = 0;
valueConstraints.gridy = yAxis;
valueConstraints.weightx = 1.0;
valueConstraints.weighty = 1.0;
valueConstraints.anchor = GridBagConstraints.WEST;
valueGbag.setConstraints(label, valueConstraints);
valuePanel.add(label);
valueConstraints.gridx = 1;
valueConstraints.gridy = yAxis;
valueConstraints.weightx = 1.0;
valueConstraints.weighty = 1.0;
valueConstraints.anchor = GridBagConstraints.WEST;
valueGbag.setConstraints(value, valueConstraints);
valuePanel.add(value);
}
/**
* @return Returns the cancelButton.
*/
public JButton getCancelButton() {
return cancelButton;
}
/**
* @return Returns the compression.
*/
public int getCompression() {
return compression.getSelectedIndex();
}
/**
* @return Returns the deliveryMode.
*/
public int getDeliveryMode() {
return deliveryMode.getSelectedIndex();
}
/**
* @return Returns the destinationName.
*/
public String getDestinationName() {
return destinationNameF.getText();
}
/**
* @return Returns the destinationType.
*/
public int getDestinationType() {
return destinationType.getSelectedIndex();
}
/**
* @return Returns the msgSize.
*/
public int getMsgSize() {
return (int) msgSize.getValue();
}
/**
* @return Returns the msgTTL.
*/
public int getMsgTTL() {
return (int) msgTTL.getValue();
}
/**
* @return Returns the msgType.
*/
public int getMsgType() {
return msgType.getSelectedIndex();
}
/**
* @return Returns the numOfMsg.
*/
public int getNumOfMsg() {
return (int) numOfMsg.getValue();
}
/**
* @return Returns the sendButton.
*/
public JButton getSendButton() {
return sendButton;
}
/**
* @return Returns the transactionType.
*/
public boolean isTransacted() {
return transactionType.getSelectedIndex() == 0;
}
/**
* @return Returns the delayBetweenMsg.
*/
public int getDelayBetweenMsg() {
return (int) delayBetweenMsg.getValue();
}
}
/**
* Dialog for receiving message for given destination topic or Queue
*/
class ReceiveMessageDialogBox extends JDialog
implements UniversalClientConstants {
private static final long serialVersionUID = 3689630285423652918L;
private JTextField destinationNameF = new JTextField("defaultDest", 15);
private JComboBox msgConsumerType = new JComboBox();
private JComboBox acknowledgeMode = new JComboBox();
private JTextField selectorF = new JTextField("", 15);
private IntegerField delayBetweenMsg = new IntegerField(2000, 15);
// buttons
private JButton receiveButton = new JButton("Receive Message");
private JButton cancelButton = new JButton("Cancel");
//
JPanel p = new JPanel(new BorderLayout());
JPanel dummyPanel = new JPanel();
JPanel valuePanel = new JPanel();
GridBagLayout valueGbag = new GridBagLayout();
GridBagConstraints valueConstraints = new GridBagConstraints();
/**
* @param owner
*/
public ReceiveMessageDialogBox(Frame owner) {
super(owner, "Universal Client: Receive Message", true);
init();
setResizable(false);
setLocationRelativeTo(owner);
}
/**
* init GUI
*/
private void init() {
int y = 0;
valuePanel.setLayout(valueGbag);
addLabelAndValueComponent("Destination Name", destinationNameF, y++);
msgConsumerType.insertItemAt("Queue ", DESTINATION_TYPE_QUEUE);
msgConsumerType.insertItemAt("Topic", DESTINATION_TYPE_TOPIC);
msgConsumerType.insertItemAt("Topic Durable",
DESTINATION_TYPE_TOPIC_DURABLE);
msgConsumerType.setSelectedIndex(DESTINATION_TYPE_QUEUE);
addLabelAndValueComponent("Msg Consumer Type", msgConsumerType, y++);
acknowledgeMode.insertItemAt("AUTO_ACKNOWLEDGE", AUTO_ACKNOWLEDGE);
acknowledgeMode.insertItemAt("CLIENT_ACKNOWLEDGE", CLIENT_ACKNOWLEDGE);
acknowledgeMode.insertItemAt("DUPS_OK_ACKNOWLEDGE", DUPS_OK_ACKNOWLEDGE);
acknowledgeMode.insertItemAt("SESSION TRANSACTED",
SESSION_TRANSACTED_MODE);
acknowledgeMode.setSelectedIndex(SESSION_TRANSACTED_MODE);
addLabelAndValueComponent("Acknowledge Mode", acknowledgeMode, y++);
addLabelAndValueComponent("Message Selector", selectorF, y++);
addLabelAndValueComponent("Delay Between Msg(ms)", delayBetweenMsg, y++);
//use a dummy panel
dummyPanel.add("Center", valuePanel);
p.add("North", dummyPanel);
//p.setBackground(Color.GRAY);
p.setBorder(BorderFactory.createEtchedBorder());
dummyPanel = new JPanel();
dummyPanel.add(receiveButton);
dummyPanel.add(cancelButton);
p.add("Center", dummyPanel);
JTextArea textArea = new JTextArea();
textArea.setFont(new Font("DialogInput", Font.BOLD, 11));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
JScrollPane areaScrollPane = new JScrollPane(textArea);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(350, 150));
String noteStr =
"Note: The first receive message for a Durable Topic will create " +
"a durable subscriber for that topic, One can keep receiving " +
"message using the durable subsrcripton, however given the same " +
"destination if the message selector is changed new durable " +
"subcription is created and the previous subscription is deleted \n \n" +
"Only one session at a time can have a TopicSubscriber for a particular durable " +
"subscription. An inactive durable subscriber is one that exists but does not " +
"currently have a message consumer associated with it. \n\n" +
"A client can change an existing durable subscription by creating a durable" +
"TopicSubscriber with the same name and a new topic and/or message selector. " +
"Changing a durable subscriber is equivalent to unsubscribing (deleting) the old " +
"one and creating a new one. ";
textArea.setText(noteStr);
textArea.setCaretPosition(0);
p.add("South", areaScrollPane);
getContentPane().add(p);
pack();
}
private void addLabelAndValueComponent(String labelStr, Component value,
int yAxis) {
JLabel label = new JLabel(labelStr, Label.RIGHT);
valueConstraints.gridx = 0;
valueConstraints.gridy = yAxis;
valueConstraints.weightx = 1.0;
valueConstraints.weighty = 1.0;
valueConstraints.anchor = GridBagConstraints.WEST;
valueGbag.setConstraints(label, valueConstraints);
valuePanel.add(label);
valueConstraints.gridx = 1;
valueConstraints.gridy = yAxis;
valueConstraints.weightx = 1.0;
valueConstraints.weighty = 1.0;
valueConstraints.anchor = GridBagConstraints.WEST;
valueGbag.setConstraints(value, valueConstraints);
valuePanel.add(value);
}
/**
* @return Returns the cancelButton.
*/
public JButton getCancelButton() {
return cancelButton;
}
/**
* @return Returns the destinationName.
*/
public String getDestinationName() {
return destinationNameF.getText();
}
/**
* @return Returns the destinationType.
*/
public int getDestinationType() {
return msgConsumerType.getSelectedIndex();
}
/**
* @return Returns the receiveButton.
*/
public JButton getReceiveButton() {
return receiveButton;
}
/**
* @return Returns the transactionType.
*/
public boolean isTransacted() {
return acknowledgeMode.getSelectedIndex() == SESSION_TRANSACTED_MODE;
}
/**
* @return Returns the selector.
*/
public String getSelector() {
return selectorF.getText();
}
/**
* @return Returns the acknowledgeMode.
*/
public int getAcknowledgeMode() {
return acknowledgeMode.getSelectedIndex();
}
/**
* @return Returns the delayBetweenMsg.
*/
public int getDelayBetweenMsg() {
return (int) delayBetweenMsg.getValue();
}
}
/**
* UniversalClient Constants
*/
interface UniversalClientConstants {
int MSG_TYPE_OBJECT = 0;
int MSG_TYPE_TEXT = 1;
int MSG_TYPE_MAP = 2;
int MSG_TYPE_BYTES = 3;
int MSG_TYPE_STREAM = 4;
//dest type
int DESTINATION_TYPE_QUEUE = 0;
int DESTINATION_TYPE_TOPIC = 1;
int DESTINATION_TYPE_TOPIC_DURABLE = 2;
//msg delivery mode
int DELIVERY_MODE_PERSISTENT = 0;
int DELIVERY_MODE_NON_PERSISTENT = 1;
//msg compression
int MSG_COMPRESSED = 0;
int MSG_NON_COMPRESSED = 1;
//session transacted
int SESSION_TRANSACTED = 0;
int SESSION_NON_TRANSACTED = 1;
//acknowledgeMode
int AUTO_ACKNOWLEDGE = 0;
int CLIENT_ACKNOWLEDGE = 1;
int DUPS_OK_ACKNOWLEDGE = 2;
int SESSION_TRANSACTED_MODE = 3;
//
int MAX_TABLE_SIZE = 30000;
String title = "Sun Java(tm) System Message Queue Universal Client";
}
class IntegerField extends JTextField {
private static final long serialVersionUID = 4050206357708159280L;
private NumberFormat format = NumberFormat.getNumberInstance();
public IntegerField(double value, int columns) {
super(columns);
format.setParseIntegerOnly(true);
Document doc = new FormattedDocument(format);
setDocument(doc);
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
IntegerField.this.getValue();
}
public void removeUpdate(DocumentEvent e) {
IntegerField.this.getValue();
}
public void changedUpdate(DocumentEvent e) {
}
});
setValue(value);
}
public double getValue() {
double retVal = 0.0;
try {
retVal = format.parse(getText()).doubleValue();
} catch (ParseException e) {
// This should never happen because insertString allows
// only properly formatted data to get in the field.
Toolkit.getDefaultToolkit().beep();
//System.err.println("getValue: could not parse: " + getText());
}
return retVal;
}
public void setValue(double value) {
setText(format.format(value));
}
}
class FormattedDocument extends PlainDocument {
private static final long serialVersionUID = 3258134673816433462L;
private Format format;
public FormattedDocument(Format f) {
format = f;
}
public Format getFormat() {
return format;
}
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(offs, currentText.length());
String proposedResult = beforeOffset + str + afterOffset;
try {
format.parseObject(proposedResult);
super.insertString(offs, str, a);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("insertString: could not parse: " +
proposedResult);
}
}
public void remove(int offs, int len) throws BadLocationException {
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(len + offs,
currentText.length());
String proposedResult = beforeOffset + afterOffset;
try {
if (proposedResult.length() != 0) {
format.parseObject(proposedResult);
}
super.remove(offs, len);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("remove: could not parse: " + proposedResult);
}
}
}
/**
* A table of JMS Messages
*/
class MsgTable extends AbstractTableModel {
private static final long serialVersionUID = 3689630306999286069L;
final String[] columnNames = {
"#", "Timestamp", "Type", "Destination", "Mode", "Priority",
"Redelivered"
};
SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:kk:mm:ss z");
LinkedList list = new LinkedList();
public int getRowCount() {
if (list == null) {
return 0;
} else {
return list.size();
}
}
public int getColumnCount() {
return columnNames.length;
}
public String getColumnName(int column) {
return columnNames[column];
}
public Object getValueAt(int row, int column) {
if ((list == null) || list.isEmpty()) {
return null;
}
Message m = (Message) list.get(row);
if (m == null) {
return "null";
}
try {
switch (column) {
case 0:
if (UniversalClientUtility.getMessageNumber(m) != null) {
return UniversalClientUtility.getMessageNumber(m);
} else { // Message number is the same as the row number
return new Integer(row);
}
case 1:
// Need to format into date/time
return df.format(new Date(m.getJMSTimestamp()));
case 2:
return (UniversalClientUtility.messageType(m));
case 3:
return UniversalClientUtility.getDestination(m);
case 4:
// Delivery mode
int mode = m.getJMSDeliveryMode();
if (mode == DeliveryMode.PERSISTENT) {
return "P";
} else if (mode == DeliveryMode.NON_PERSISTENT) {
return "NP";
} else {
return String.valueOf(mode) + "?";
}
case 5:
// Priority
return new Integer(m.getJMSPriority());
case 6:
return new Boolean(m.getJMSRedelivered());
default:
return "Bad column value: " + column;
}
} catch (JMSException e) {
return ("Error: " + e);
}
}
/**
* Load and enumeration of messages into the table
*/
int load(Enumeration e) {
if (e == null) {
return 0;
}
list = new LinkedList();
while (e.hasMoreElements()) {
list.add(e.nextElement());
}
fireTableDataChanged();
return list.size();
}
/**
* adss message to table
*/
int addMessage(Message msg) {
list.add(msg);
return list.size();
}
public void updateUI() {
fireTableRowsInserted(list.size() - 1, list.size());
}
public void clearData() {
list.clear();
fireTableDataChanged();
}
int load(List l) {
if (l == null) {
return 0;
}
if (l.size() == list.size()) {
return list.size();
}
list = new LinkedList(l);
fireTableDataChanged();
return list.size();
}
Message getMessageAtRow(int row) {
if (list == null) {
return null;
}
return ((Message) list.get(row));
}
}
/**
* A panel with a text area that knows how to format and display a HashMap
* of values.
*/
class PropertyPanel extends JPanel {
private static final long serialVersionUID = 3257288045550974257L;
JLabel label = null;
JTextArea textArea = null;
JScrollPane areaScrollPane = null;
PropertyPanel() {
super(true);
setBorder(BorderFactory.createEtchedBorder());
setLayout(new BorderLayout());
label = new JLabel();
textArea = new JTextArea();
textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
areaScrollPane = new JScrollPane(textArea);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(500, 150));
add(BorderLayout.NORTH, label);
add(BorderLayout.CENTER, areaScrollPane);
}
void setTitle(String title) {
label.setText(title);
}
/**
* Display a HashMap in the text window
*/
void load(HashMap map) {
StringBuffer buf = new StringBuffer();
Set entries = map.entrySet();
Map.Entry entry = null;
Iterator iter = entries.iterator();
while (iter.hasNext()) {
entry = (Map.Entry) iter.next();
String key = entry.getKey().toString();
Object o = entry.getValue();
String value = "";
if (o != null) {
value = o.toString();
}
buf.append(pad(key + ": ", 20));
buf.append(value + "\n");
}
textArea.setText(buf.toString());
textArea.setCaretPosition(0);
areaScrollPane.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
}
/**
* Display text in the text window
*/
void load(String s) {
textArea.setText(s);
}
/**
* Pad a string to the specified width, right justified. If the string
* is longer than the width you get back the original string.
*/
String pad(String s, int width) {
// Very inefficient, but we don"t care
StringBuffer sb = new StringBuffer();
int padding = width - s.length();
if (padding <= 0) {
return s;
}
while (padding > 0) {
sb.append(" ");
padding--;
}
sb.append(s);
return sb.toString();
}
}
class UniversalClientUtility {
public static String[] pad = { "", "0", "00", "000", "0000" };
public static void dumpException(Exception e) {
Exception linked = null;
if (e instanceof JMSException) {
linked = ((JMSException) e).getLinkedException();
}
if (linked == null) {
e.printStackTrace();
} else {
System.err.println(e.toString());
linked.printStackTrace();
}
}
public static String getMessageNumber(Message m) throws JMSException {
if (m.propertyExists("msgNum") && m.propertyExists("totalNumMsgs")) {
int msgNum = m.getIntProperty("msgNum");
int totalNumMsgs = m.getIntProperty("totalNumMsgs");
return msgNum + " of " + totalNumMsgs;
}
return null;
}
public static String getDestination(Message m) throws JMSException {
Destination d = m.getJMSDestination();
String s = null;
if (d != null) {
if (d instanceof Queue) {
s = "Queue: " + ((Queue) d).getQueueName();
} else {
s = "Topic: " + ((Topic) d).getTopicName();
}
} else {
s = "";
}
return s;
}
/**
* Return a string description of the type of JMS message
*/
public static String messageType(Message m) {
if (m instanceof TextMessage) {
return "TextMessage";
} else if (m instanceof BytesMessage) {
return "BytesMessage";
} else if (m instanceof MapMessage) {
return "MapMessage";
} else if (m instanceof ObjectMessage) {
return "ObjectMessage";
} else if (m instanceof StreamMessage) {
return "StreamMessage";
} else if (m instanceof Message) {
return "Message";
} else {
// Unknown Message type
String type = m.getClass().getName();
StringTokenizer st = new StringTokenizer(type, ".");
String s = null;
while (st.hasMoreElements()) {
s = st.nextToken();
}
return s;
}
}
/**
* Return a string representation of the body of a JMS bytes message. This
* is basically a hex dump of the body. Note, this only looks at the first
* 1K of the message body.
*/
public static String jmsBytesBodyAsString(Message m) {
byte[] body = new byte[1024];
int n = 0;
if (m instanceof BytesMessage) {
try {
((BytesMessage) m).reset();
n = ((BytesMessage) m).readBytes(body);
} catch (JMSException ex) {
return (ex.toString());
}
} else if (m instanceof StreamMessage) {
try {
((StreamMessage) m).reset();
n = ((StreamMessage) m).readBytes(body);
} catch (JMSException ex) {
return (ex.toString());
}
}
if (n <= 0) {
return "<empty body>";
} else {
return (toHexDump(body, n) + ((n >= body.length) ? "\n. . ." : ""));
}
}
/**
* Return a string representation of a JMS message body
*/
public static String jmsMsgBodyAsString(Message m) {
if (m instanceof TextMessage) {
try {
return ((TextMessage) m).getText();
} catch (JMSException ex) {
return ex.toString();
}
} else if (m instanceof BytesMessage) {
return jmsBytesBodyAsString(m);
} else if (m instanceof MapMessage) {
MapMessage msg = (MapMessage) m;
HashMap props = new HashMap();
// Get all MapMessage properties and stuff into a hash table
try {
for (Enumeration enu = msg.getMapNames();
enu.hasMoreElements();) {
String name = (enu.nextElement()).toString();
props.put(name, (msg.getObject(name)).toString());
}
return props.toString();
} catch (JMSException ex) {
return (ex.toString());
}
} else if (m instanceof ObjectMessage) {
ObjectMessage msg = (ObjectMessage) m;
Object obj = null;
try {
obj = msg.getObject();
if (obj != null) {
return obj.toString();
} else {
return "null";
}
} catch (Exception ex) {
return (ex.toString());
}
} else if (m instanceof StreamMessage) {
return jmsBytesBodyAsString(m);
} else if (m instanceof Message) {
return "Can"t get body for message of type Message";
}
return "Unknown message type " + m;
}
/**
* Takes the JMS header fields of a JMS message and puts them in a HashMap
*/
public static HashMap jmsHeadersToHashMap(Message m)
throws JMSException {
HashMap hdrs = new HashMap();
String s = null;
s = m.getJMSCorrelationID();
hdrs.put("JMSCorrelationID", s);
s = String.valueOf(m.getJMSDeliveryMode());
hdrs.put("JMSDeliverMode", s);
Destination d = m.getJMSDestination();
if (d != null) {
if (d instanceof Queue) {
s = ((Queue) d).getQueueName() + " : Queue";
} else {
s = ((Topic) d).getTopicName() + " : Topic";
}
} else {
s = "";
}
hdrs.put("JMSDestination", s);
s = String.valueOf(m.getJMSExpiration());
hdrs.put("JMSExpiration", s);
s = m.getJMSMessageID();
hdrs.put("JMSMessageID", s);
s = String.valueOf(m.getJMSPriority());
hdrs.put("JMSPriority", s);
s = String.valueOf(m.getJMSRedelivered());
hdrs.put("JMSRedelivered", s);
d = m.getJMSDestination();
if (d != null) {
if (d instanceof Queue) {
s = ((Queue) d).getQueueName();
} else {
s = ((Topic) d).getTopicName();
}
} else {
s = "";
}
hdrs.put("JMSReplyTo", s);
s = String.valueOf(m.getJMSTimestamp());
hdrs.put("JMSTimestamp", s);
s = m.getJMSType();
hdrs.put("JMSType", s);
return hdrs;
}
/**
* Takes a buffer of bytes and returns a hex dump. Each hex digit represents
* 4 bits. The hex digits are formatted into groups of 4 (2 bytes, 16 bits).
* Each line has 8 groups, so each line represents 128 bits.
*/
public static String toHexDump(byte[] buf, int length) {
// Buffer must be an even length
if ((buf.length % 2) != 0) {
throw new IllegalArgumentException();
}
int value;
StringBuffer sb = new StringBuffer(buf.length * 2);
/*
* Assume buf is in network byte order (most significant byte is
* buf[0]). Convert two byte pairs to a short, then display as a hex
* string.
*/
int n = 0;
while ((n < buf.length) && (n < length)) {
value = buf[n + 1] & 0xFF; // Lower byte
value |= ((buf[n] << 8) & 0xFF00); // Upper byte
String s = Integer.toHexString(value);
// Left bad with 0"s
sb.append(pad[4 - s.length()]);
sb.append(s);
n += 2;
if ((n % 16) == 0) {
sb.append("\n");
} else {
sb.append(" ");
}
}
return sb.toString();
}
public static Rectangle getRowBounds(JTable table, int row) {
checkRow(table, row);
Rectangle result = table.getCellRect(row, -1, true);
Insets i = table.getInsets();
result.x = i.left;
result.width = table.getWidth() - i.left - i.right;
return result;
}
private static void checkRow(JTable table, int row) {
if (row < 0) {
throw new IndexOutOfBoundsException(row + " < 0");
}
if (row >= table.getRowCount()) {
throw new IndexOutOfBoundsException(row + " >= " +
table.getRowCount());
}
}
/*
* Set the properties on this object.
*/
public static void setConnFactoryProperties(
com.sun.messaging.AdministeredObject obj, Properties objProps)
throws JMSException {
/*
* Set the specified properties on the new object.
*/
for (Enumeration e = objProps.propertyNames(); e.hasMoreElements();) {
String propName = (String) e.nextElement();
String value = objProps.getProperty(propName);
if (value != null) {
try {
obj.setProperty(propName, value.trim());
} catch (JMSException je) {
throw je;
}
}
}
}
}
class StatusArea extends JPanel {
private static final long serialVersionUID = 3618421531575793975L;
private JTextArea statusTextArea;
/**
* Create status bar for uclient console application.
*/
public StatusArea() {
super(true);
setLayout(new BorderLayout());
statusTextArea = new JTextArea(4, 60);
//statusTextArea = new JTextArea();
statusTextArea.setLineWrap(true);
statusTextArea.setForeground(Color.BLUE);
statusTextArea.setEditable(false);
JScrollPane statusTextPane = new JScrollPane(statusTextArea);
add(statusTextPane, BorderLayout.CENTER);
}
/**
* Append status text to the text area.
*
* @param statusText the status text
*/
public void appendText(String statusText) {
statusText = statusText + "\n";
statusTextArea.append(statusText);
statusTextArea.setCaretPosition(statusTextArea.getText().length());
}
/*
* Clears the text shown in the Status Area.
*/
public void clearText() {
statusTextArea.setText("");
}
}
The use of a message listener in the publish/subscribe model. The producer publishes several messages, and the consumer reads them asynchronously
/*
* @(#)AsynchTopicExample.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import javax.jms.*;
/**
* The AsynchTopicExample class demonstrates the use of a message listener in
* the publish/subscribe model. The producer publishes several messages, and
* the consumer reads them asynchronously.
* <p>
* The program contains a MultipleProducer class, an AsynchConsumer class
* with a listener class, a main method, and a method that runs the consumer
* and producer threads.
* <p>
* Specify a topic name on the command line when you run the program. The
* program also uses a queue named "controlQueue", which should be created
* before you run the program.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class AsynchTopicExample {
final String CONTROL_QUEUE = "controlQueue";
String topicName = null;
int exitResult = 0;
/**
* The AsynchConsumer class fetches several messages from a topic
* asynchronously, using a message listener, TextListener.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class AsynchConsumer extends Thread {
/**
* The TextListener class implements the MessageListener interface by
* defining an onMessage method for the AsynchConsumer class.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
private class TextListener implements MessageListener {
final SampleUtilities.DoneLatch monitor =
new SampleUtilities.DoneLatch();
/**
* Casts the message to a TextMessage and displays its text.
* A non-text message is interpreted as the end of the message
* stream, and the message listener sets its monitor state to all
* done processing messages.
*
* @param message the incoming message
*/
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage msg = (TextMessage) message;
try {
System.out.println("CONSUMER THREAD: Reading message: "
+ msg.getText());
} catch (JMSException e) {
System.out.println("Exception in onMessage(): "
+ e.toString());
}
} else {
monitor.allDone();
}
}
}
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
MessageConsumer msgConsumer = null;
TextListener topicListener = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create consumer.
* Register message listener (TextListener).
* Start message delivery.
* Send synchronize message to producer, then wait till all
* messages have arrived.
* Listener displays the messages obtained.
*/
try {
msgConsumer = session.createConsumer(topic);
topicListener = new TextListener();
msgConsumer.setMessageListener(topicListener);
connection.start();
// Let producer know that consumer is ready.
try {
SampleUtilities.sendSynchronizeMessage("CONSUMER THREAD: ",
CONTROL_QUEUE);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Asynchronously process messages.
* Block until producer issues a control message indicating
* end of publish stream.
*/
topicListener.monitor.waitTillDone();
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The MultipleProducer class publishes several message to a topic.
*
* @author Kim Haase
* @version 1.6, 08/18/00
*/
public class MultipleProducer extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
MessageProducer msgProducer = null;
TextMessage message = null;
final int NUMMSGS = 20;
final String MSG_TEXT = new String("Here is a message");
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* After synchronizing with consumer, create producer.
* Create text message.
* Send messages, varying text slightly.
* Send end-of-messages message.
* Finally, close connection.
*/
try {
/*
* Synchronize with consumer. Wait for message indicating
* that consumer is ready to receive messages.
*/
try {
SampleUtilities.receiveSynchronizeMessages("PRODUCER THREAD: ",
CONTROL_QUEUE, 1);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
msgProducer = session.createProducer(topic);
message = session.createTextMessage();
for (int i = 0; i < NUMMSGS; i++) {
message.setText(MSG_TEXT + " " + (i + 1));
System.out.println("PRODUCER THREAD: Publishing message: "
+ message.getText());
msgProducer.send(message);
}
// Send a non-text control message indicating end of messages.
msgProducer.send(session.createMessage());
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* Instantiates the consumer and producer classes and starts their
* threads.
* Calls the join method to wait for the threads to die.
* <p>
* It is essential to start the consumer before starting the producer.
* In the publish/subscribe model, a consumer can ordinarily receive only
* messages published while it is active.
*/
public void run_threads() {
AsynchConsumer asynchConsumer = new AsynchConsumer();
MultipleProducer multipleProducer = new MultipleProducer();
multipleProducer.start();
asynchConsumer.start();
try {
asynchConsumer.join();
multipleProducer.join();
} catch (InterruptedException e) {}
}
/**
* Reads the topic name from the command line, then calls the
* run_threads method to execute the program threads.
*
* @param args the topic used by the example
*/
public static void main(String[] args) {
AsynchTopicExample ate = new AsynchTopicExample();
if (args.length != 1) {
System.out.println("Usage: java AsynchTopicExample <topic_name>");
System.exit(1);
}
ate.topicName = new String(args[0]);
System.out.println("Topic name is " + ate.topicName);
ate.run_threads();
SampleUtilities.exit(ate.exitResult);
}
}
The use of message header fields
/*
* @(#)MessageHeadersTopic.java 1.3 02/05/02
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.sql.*;
import java.util.*;
import javax.jms.*;
/**
* The MessageHeadersTopic class demonstrates the use of message header fields.
* <p>
* The program contains a HeaderProducer class, a HeaderConsumer class, a
* display_headers() method that is called by both classes, a main method, and
* a method that runs the consumer and producer threads.
* <p>
* The producing class sends three messages, and the consuming class
* receives them. The program displays the message headers just before the
* send call and just after the receive so that you can see which ones are
* set by the send method.
* <p>
* Specify a topic name on the command line when you run the program. The
* program also uses a queue named "controlQueue", which should be created
* before you run the program.
*
* @author Kim Haase
* @version 1.8, 08/18/00
*/
public class MessageHeadersTopic {
final String CONTROL_QUEUE = "controlQueue";
String topicName = null;
int exitResult = 0;
/**
* The HeaderProducer class sends three messages, setting the JMSType
* message header field, one of three header fields that are not set by
* the send method. (The others, JMSCorrelationID and JMSReplyTo, are
* demonstrated in the RequestReplyQueue example.) It also sets a
* client property, "messageNumber".
*
* The displayHeaders method is called just before the send method.
*
* @author Kim Haase
* @version 1.8, 08/18/00
*/
public class HeaderProducer extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
javax.jms.Connection connection = null;
Session session = null;
Topic topic = null;
MessageProducer msgProducer = null;
TextMessage message = null;
final String MSG_TEXT = new String("Read My Headers");
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
try {
/*
* Synchronize with consumer. Wait for message indicating
* that consumer is ready to receive messages.
*/
try {
SampleUtilities.receiveSynchronizeMessages("PRODUCER THREAD: ",
CONTROL_QUEUE, 1);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
// Create producer.
msgProducer = session.createProducer(topic);
// First message: no-argument form of send method
message = session.createTextMessage();
message.setJMSType("Simple");
System.out.println("PRODUCER THREAD: Setting JMSType to "
+ message.getJMSType());
message.setIntProperty("messageNumber", 1);
System.out.println("PRODUCER THREAD: Setting client property messageNumber to "
+ message.getIntProperty("messageNumber"));
message.setText(MSG_TEXT);
System.out.println("PRODUCER THREAD: Setting message text to: "
+ message.getText());
System.out.println("PRODUCER THREAD: Headers before message is sent:");
displayHeaders(message, "PRODUCER THREAD: ");
msgProducer.send(message);
/*
* Second message: 3-argument form of send method;
* explicit setting of delivery mode, priority, and
* expiration
*/
message = session.createTextMessage();
message.setJMSType("Less Simple");
System.out.println("\nPRODUCER THREAD: Setting JMSType to "
+ message.getJMSType());
message.setIntProperty("messageNumber", 2);
System.out.println("PRODUCER THREAD: Setting client property messageNumber to "
+ message.getIntProperty("messageNumber"));
message.setText(MSG_TEXT + " Again");
System.out.println("PRODUCER THREAD: Setting message text to: "
+ message.getText());
displayHeaders(message, "PRODUCER THREAD: ");
msgProducer.send(message, DeliveryMode.NON_PERSISTENT,
3, 10000);
/*
* Third message: no-argument form of send method,
* MessageID and Timestamp disabled
*/
message = session.createTextMessage();
message.setJMSType("Disable Test");
System.out.println("\nPRODUCER THREAD: Setting JMSType to "
+ message.getJMSType());
message.setIntProperty("messageNumber", 3);
System.out.println("PRODUCER THREAD: Setting client property messageNumber to "
+ message.getIntProperty("messageNumber"));
message.setText(MSG_TEXT
+ " with MessageID and Timestamp disabled");
System.out.println("PRODUCER THREAD: Setting message text to: "
+ message.getText());
msgProducer.setDisableMessageID(true);
msgProducer.setDisableMessageTimestamp(true);
System.out.println("PRODUCER THREAD: Disabling Message ID and Timestamp");
displayHeaders(message, "PRODUCER THREAD: ");
msgProducer.send(message);
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* The HeaderConsumer class receives the three messages and calls the
* displayHeaders method to show how the send method changed the
* header values.
* <p>
* The first message, in which no fields were set explicitly by the send
* method, shows the default values of these fields.
* <p>
* The second message shows the values set explicitly by the send method.
* <p>
* The third message shows whether disabling the MessageID and Timestamp
* has any effect in the current JMS implementation.
*
* @author Kim Haase
* @version 1.8, 08/18/00
*/
public class HeaderConsumer extends Thread {
/**
* Runs the thread.
*/
public void run() {
ConnectionFactory connectionFactory = null;
javax.jms.Connection connection = null;
Session session = null;
Topic topic = null;
MessageConsumer msgConsumer = null;
final boolean NOLOCAL = true;
TextMessage message = null;
try {
connectionFactory =
SampleUtilities.getConnectionFactory();
connection =
connectionFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = SampleUtilities.getTopic(topicName, session);
} catch (Exception e) {
System.out.println("Connection problem: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
/*
* Create consumer and start message delivery.
* Send synchronize message to producer.
* Receive the three messages.
* Call the displayHeaders method to display the message headers.
*/
try {
msgConsumer =
session.createConsumer(topic, null, NOLOCAL);
connection.start();
// Let producer know that consumer is ready.
try {
SampleUtilities.sendSynchronizeMessage("CONSUMER THREAD: ",
CONTROL_QUEUE);
} catch (Exception e) {
System.out.println("Queue probably missing: " + e.toString());
if (connection != null) {
try {
connection.close();
} catch (JMSException ee) {}
}
System.exit(1);
}
for (int i = 0; i < 3; i++) {
message = (TextMessage) msgConsumer.receive();
System.out.println("\nCONSUMER THREAD: Message received: "
+ message.getText());
System.out.println("CONSUMER THREAD: Headers after message is received:");
displayHeaders(message, "CONSUMER THREAD: ");
}
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
exitResult = 1;
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
exitResult = 1;
}
}
}
}
}
/**
* Displays all message headers. Each display is in a try/catch block in
* case the header is not set before the message is sent.
*
* @param message the message whose headers are to be displayed
* @param prefix the prefix (producer or consumer) to be displayed
*/
public void displayHeaders (Message message, String prefix) {
Destination dest = null;
int delMode = 0;
long expiration = 0;
Time expTime = null;
int priority = 0;
String msgID = null;
long timestamp = 0;
Time timestampTime = null;
String correlID = null;
Destination replyTo = null;
boolean redelivered = false;
String type = null;
String propertyName = null;
try {
System.out.println(prefix + "Headers set by send method: ");
// Display the destination (topic, in this case).
try {
dest = message.getJMSDestination();
System.out.println(prefix + " JMSDestination: " + dest);
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display the delivery mode.
try {
delMode = message.getJMSDeliveryMode();
System.out.print(prefix);
if (delMode == DeliveryMode.NON_PERSISTENT) {
System.out.println(" JMSDeliveryMode: non-persistent");
} else if (delMode == DeliveryMode.PERSISTENT) {
System.out.println(" JMSDeliveryMode: persistent");
} else {
System.out.println(" JMSDeliveryMode: neither persistent nor non-persistent; error");
}
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
/*
* Display the expiration time. If value is 0 (the default),
* the message never expires. Otherwise, cast the value
* to a Time object for display.
*/
try {
expiration = message.getJMSExpiration();
System.out.print(prefix);
if (expiration != 0) {
expTime = new Time(expiration);
System.out.println(" JMSExpiration: " + expTime);
} else {
System.out.println(" JMSExpiration: " + expiration);
}
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display the priority.
try {
priority = message.getJMSPriority();
System.out.println(prefix + " JMSPriority: " + priority);
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display the message ID.
try {
msgID = message.getJMSMessageID();
System.out.println(prefix + " JMSMessageID: " + msgID);
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
/*
* Display the timestamp.
* If value is not 0, cast it to a Time object for display.
*/
try {
timestamp = message.getJMSTimestamp();
System.out.print(prefix);
if (timestamp != 0) {
timestampTime = new Time(timestamp);
System.out.println(" JMSTimestamp: " + timestampTime);
} else {
System.out.println(" JMSTimestamp: " + timestamp);
}
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display the correlation ID.
try {
correlID = message.getJMSCorrelationID();
System.out.println(prefix + " JMSCorrelationID: " + correlID);
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display the ReplyTo destination.
try {
replyTo = message.getJMSReplyTo();
System.out.println(prefix + " JMSReplyTo: " + replyTo);
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display the Redelivered value (usually false).
System.out.println(prefix + "Header set by JMS provider:");
try {
redelivered = message.getJMSRedelivered();
System.out.println(prefix + " JMSRedelivered: " + redelivered);
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display the JMSType.
System.out.println(prefix + "Headers set by client program:");
try {
type = message.getJMSType();
System.out.println(prefix + " JMSType: " + type);
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
// Display any client properties.
try {
for (Enumeration e = message.getPropertyNames(); e.hasMoreElements() ;) {
propertyName = new String((String) e.nextElement());
System.out.println(prefix + " Client property "
+ propertyName + ": "
+ message.getObjectProperty(propertyName));
}
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
} catch (Exception e) {
System.out.println(prefix + "Exception occurred: "
+ e.toString());
exitResult = 1;
}
}
/**
* Instantiates the consumer and producer classes and starts their
* threads.
* Calls the join method to wait for the threads to die.
* <p>
* It is essential to start the consumer before starting the producer.
* In the send/subscribe model, a consumer can ordinarily receive only
* messages sent while it is active.
*/
public void run_threads() {
HeaderConsumer headerConsumer = new HeaderConsumer();
HeaderProducer headerProducer = new HeaderProducer();
headerConsumer.start();
headerProducer.start();
try {
headerConsumer.join();
headerProducer.join();
} catch (InterruptedException e) {}
}
/**
* Reads the topic name from the command line, then calls the
* run_threads method to execute the program threads.
*
* @param args the topic used by the example
*/
public static void main(String[] args) {
MessageHeadersTopic mht = new MessageHeadersTopic();
if (args.length != 1) {
System.out.println("Usage: java MessageHeadersTopic <topic_name>");
System.exit(1);
}
mht.topicName = new String(args[0]);
System.out.println("Topic name is " + mht.topicName);
mht.run_threads();
SampleUtilities.exit(mht.exitResult);
}
}
The VMMetrics example is a JMS application that monitors the Java VM used by the Sun Java(tm) System Message Queue broker
/*
* @(#)VMMetrics.java 1.3 04/01/05
*
* Copyright (c) 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.util.Enumeration;
import java.util.Properties;
import javax.jms.*;
/**
* The VMMetrics example is a JMS application that monitors the
* Java VM used by the Sun Java(tm) System Message Queue broker. It does so by
* subscribing to a topic named "mq.metrics.jvm". The messages that arrive
* contain Java VM information such as:
* - amount of free memory
* - amount of maximum memory
* - total amount of memory
*
* By default VMMetrics will connect to the broker running on localhost:7676.
* You can use -DimqAddressList attribute to change the host, port and
* transport:
*
* java -DimqAddressList=mq://<host>:<port>/jms VMMetrics
*/
public class VMMetrics implements MessageListener {
ConnectionFactory metricConnectionFactory;
Connection metricConnection;
Session metricSession;
MessageConsumer metricConsumer;
Topic metricTopic;
MetricsPrinter mp;
int rowsPrinted = 0;
public static void main(String args[]) {
VMMetrics bm = new VMMetrics();
bm.initPrinter();
bm.initJMS();
bm.subscribeToMetric();
}
/*
* Initializes the class that does the printing, MetricsPrinter.
* See the MetricsPrinter class for details.
*/
private void initPrinter() {
String oneRow[] = new String[ 3 ];
int i = 0;
mp = new MetricsPrinter(3, 2, "-");
i = 0;
oneRow[i++] = "Free Memory";
oneRow[i++] = "Max Memory";
oneRow[i++] = "Total Memory";
mp.addTitle(oneRow);
}
/**
* Create the Connection and Session etc.
*/
public void initJMS() {
try {
metricConnectionFactory = new com.sun.messaging.ConnectionFactory();
metricConnection = metricConnectionFactory.createConnection();
metricConnection.start();
// creating Session
// Transaction Mode: None
// Acknowledge Mode: Automatic
metricSession = metricConnection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch(Exception e) {
System.err.println("Cannot create metric connection or session: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
public void subscribeToMetric() {
try {
metricTopic = metricSession.createTopic("mq.metrics.jvm");
metricConsumer = metricSession.createConsumer(metricTopic);
metricConsumer.setMessageListener(this);
} catch(JMSException e) {
System.err.println("Cannot subscribe to metric topic: "
+ e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
/*
* When a metric message arrives
* - verify it"s type
* - extract it"s fields
* - print one row of output
*/
public void onMessage(Message m) {
try {
MapMessage mapMsg = (MapMessage)m;
String type = mapMsg.getStringProperty("type");
if (type.equals("mq.metrics.jvm")) {
String oneRow[] = new String[ 3 ];
int i = 0;
/*
* Extract broke metrics
*/
oneRow[i++] = Long.toString(mapMsg.getLong("freeMemory"));
oneRow[i++] = Long.toString(mapMsg.getLong("maxMemory"));
oneRow[i++] = Long.toString(mapMsg.getLong("totalMemory"));
mp.add(oneRow);
if ((rowsPrinted % 20) == 0) {
mp.print();
} else {
mp.print(false);
}
rowsPrinted++;
mp.clear();
} else {
System.err.println("Msg received: not vm metric type");
}
} catch (Exception e) {
System.err.println("onMessage: Exception caught: " + e);
}
}
}
This example illustrates how JMS can be used to create a simple chat application
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
================================================================================
@(#)README 1.7 03/22/05
================================================================================
SimpleChat example
Description
-----------
This example illustrates how JMS can be used to create a simple
chat application. This example uses JMS Topics and each instance
of the the chat application that you run is a TopicPublisher and
TopicSubscriber. SimpleChat.java does not use JNDI and relies on
the feature by which a broker can "auto-create" the destinations
desired by the user. The bulk of the application deals with the
user interface and the JMS related code is fairly straightforward.
Files
-----
SimpleChat.java Source file for this example.
*.class Prebuilt Java class files for this example.
README This file.
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer"s Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac SimpleChat.java
Running the example
-------------------
Run the following:
java SimpleChat
The application comes up not connected to any chat session.
To join a chat session, bring down the "Chat" menu and
select the "Connect ..." menu item. A dialog will appear to
query for a "Chat User Name", and the "Chat Topic" to join.
The Chat User Name is simply used to label your messages when
they appear on the "Messages in chat" textarea. The default value
for this is the "user.name" system property.
The Chat Topic is the topic name used to determine who to deliver
chat messages to i.e. the participants in the chat. The default
value is "defaulttopic".
After selecting the above 2 values (using the default values is
fine), click on the "Connect" button. The application is now
in the chat session.
From now on, you can broadcast messages to the chat participants
by typing in the textarea at the bottom (marked "Type Message:")
and selecting the "send Message as <chat name>" button.
More than one instance of the chat application will make the demo
more interesting - for all of the chat applications to talk to
one another they need to be using the same Chat Topic.
To leave the chat session, bring down the "Chat" menu and select
the "Disconnect" menu item.
To clear the "Messages in chat" textarea, bring down the "Chat"
menu and select the "Clear Messages" menu item.
To exit the simplechat demo application/program, bring down the "Chat"
menu and select the "Exit" menu item.
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import java.net.InetAddress;
import java.util.Vector;
import java.util.Enumeration;
import javax.jms.*;
/**
* The SimpleChat example is a basic "chat" application that uses
* the JMS APIs. It uses JMS Topics to represent chat rooms or
* chat topics.
*
* When the application is launched, use the "Chat" menu to
* start or connect to a chat session.
*
* The command line option "-DimqAddressList="can be used to affect
* how the application connects to the message service provided by
* the Sun Java(tm) System Message Queue software.
*
* It should be pointed out that the bulk of the application is
* AWT - code for the GUI. The code that implements the messages
* sent/received by the chat application is small in size.
*
* The SimpleChat example consists of the following classes, all
* contained in one file:
*
* SimpleChat - contains main() entry point, GUI/JMS
* initialization code.
* SimpleChatPanel - GUI for message textareas.
* SimpleChatDialog - GUI for "Connect" popup dialog.
* ChatObjMessage - chat message class.
*
* Description of the ChatObjMessage class and how it is used
* ==========================================================
* The ChatObjMessage class is used to broadcast messages in
* the JMS simplechat example.
* The interface SimpleChatMessageTypes (defined in this file)
* has several message "types":
*
* From the interface definition:
* public static int JOIN = 0;
* public static int MSG = 1;
* public static int LEAVE = 2;
*
* JOIN - for applications to announce that they just joined the chat
* MSG - for normal text messages
* LEAVE - for applications to announce that are leaving the chat
*
* Each ChatObjMessage also has fields to indicate who the sender is
* - a simple String identifier.
*
* When the chat application enters a chat session, it broadcasts a JOIN
* message. Everybody currently in the chat session will get this and
* the chat GUI will recognize the message of type JOIN and will print
* something like this in the "Messages in chat:" textarea:
*
* *** johndoe has joined chat session
*
* Once an application has entered a chat session, messages sent as part of
* a normal "chat" are sent as ChatObjMessage"s of type MSG. Upon seeing
* these messages, the chat GUI simply displays the sender and the message
* text as follows:
*
* johndoe: Hello World !
*
* When a chat disconnect is done, prior to doing the various JMS cleanup
* operations, a LEAVE message is sent. The chat GUI sees this and prints
* something like:
*
* *** johndoe has left chat session
*
*
*/
public class SimpleChat implements ActionListener,
WindowListener,
MessageListener {
ConnectionFactory connectionFactory;
Connection connection;
Session session;
MessageProducer msgProducer;
MessageConsumer msgConsumer;
Topic topic;
boolean connected = false;
String name, hostName, topicName, outgoingMsgTypeString;
int outgoingMsgType;
Frame frame;
SimpleChatPanel scp;
SimpleChatDialog scd = null;
MenuItem connectItem, disconnectItem, clearItem, exitItem;
Button sendB, connectB, cancelB;
SimpleChatMessageCreator outgoingMsgCreator;
SimpleChatMessageCreator txtMsgCreator, objMsgCreator, mapMsgCreator, bytesMsgCreator, streamMsgCreator;
/**
* @param args Arguments passed via the command line. These are
* used to create the ConnectionFactory.
*/
public static void main(String[] args) {
SimpleChat sc = new SimpleChat();
sc.initGui();
sc.initJms(args);
}
/**
* SimpleChat constructor.
* Initializes the chat user name, topic, hostname.
*/
public SimpleChat() {
name = System.getProperty("user.name", "johndoe");
topicName = "defaulttopic";
try {
hostName = InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
hostName = "localhost";
}
}
public SimpleChatMessageCreator getMessageCreator(int type) {
switch (type) {
case SimpleChatDialog.MSG_TYPE_TEXT:
if (txtMsgCreator == null) {
txtMsgCreator = new SimpleChatTextMessageCreator();
}
return (txtMsgCreator);
case SimpleChatDialog.MSG_TYPE_OBJECT:
if (objMsgCreator == null) {
objMsgCreator = new SimpleChatObjMessageCreator();
}
return (objMsgCreator);
case SimpleChatDialog.MSG_TYPE_MAP:
if (mapMsgCreator == null) {
mapMsgCreator = new SimpleChatMapMessageCreator();
}
return (mapMsgCreator);
case SimpleChatDialog.MSG_TYPE_BYTES:
if (bytesMsgCreator == null) {
bytesMsgCreator = new SimpleChatBytesMessageCreator();
}
return (bytesMsgCreator);
case SimpleChatDialog.MSG_TYPE_STREAM:
if (streamMsgCreator == null) {
streamMsgCreator = new SimpleChatStreamMessageCreator();
}
return (streamMsgCreator);
}
return (null);
}
public SimpleChatMessageCreator getMessageCreator(Message msg) {
if (msg instanceof TextMessage) {
if (txtMsgCreator == null) {
txtMsgCreator = new SimpleChatTextMessageCreator();
}
return (txtMsgCreator);
} else if (msg instanceof ObjectMessage) {
if (objMsgCreator == null) {
objMsgCreator = new SimpleChatObjMessageCreator();
}
return (objMsgCreator);
} else if (msg instanceof MapMessage) {
if (mapMsgCreator == null) {
mapMsgCreator = new SimpleChatMapMessageCreator();
}
return (mapMsgCreator);
} else if (msg instanceof BytesMessage) {
if (bytesMsgCreator == null) {
bytesMsgCreator = new SimpleChatBytesMessageCreator();
}
return (bytesMsgCreator);
} else if (msg instanceof StreamMessage) {
if (streamMsgCreator == null) {
streamMsgCreator = new SimpleChatStreamMessageCreator();
}
return (streamMsgCreator);
}
return (null);
}
/*
* BEGIN INTERFACE ActionListener
*/
/**
* Detects the various UI actions and performs the
* relevant action:
* Connect menu item (on Chat menu): Show Connect dialog
* Disconnect menu item (on Chat menu): Disconnect from chat
* Connect button (on Connect dialog): Connect to specified
* chat
* Cancel button (on Connect dialog): Hide Connect dialog
* Send button: Send message to chat
* Clear menu item (on Chat menu): Clear chat textarea
* Exit menu item (on Chat menu): Exit application
*
* @param ActionEvent UI event
*/
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == connectItem) {
queryForChatNames();
} else if (obj == disconnectItem) {
doDisconnect();
} else if (obj == connectB) {
scd.setVisible(false);
topicName = scd.getChatTopicName();
name = scd.getChatUserName();
outgoingMsgTypeString = scd.getMsgTypeString();
outgoingMsgType = scd.getMsgType();
doConnect();
} else if (obj == cancelB) {
scd.setVisible(false);
} else if (obj == sendB) {
sendNormalMessage();
} else if (obj == clearItem) {
scp.clear();
} else if (obj == exitItem) {
exit();
}
}
/*
* END INTERFACE ActionListener
*/
/*
* BEGIN INTERFACE WindowListener
*/
public void windowClosing(WindowEvent e) {
e.getWindow().dispose();
}
public void windowClosed(WindowEvent e) {
exit();
}
public void windowActivated(WindowEvent e) { }
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified(WindowEvent e) { }
public void windowOpened(WindowEvent e) { }
/*
* END INTERFACE WindowListener
*/
/*
* BEGIN INTERFACE MessageListener
*/
/**
* Display chat message on gui.
*
* @param msg message received
*/
public void onMessage(Message msg) {
String sender, msgText;
int type;
SimpleChatMessageCreator inboundMsgCreator;
inboundMsgCreator = getMessageCreator(msg);
if (inboundMsgCreator == null) {
errorMessage("Message received is not supported ! ");
return;
}
/*
* Need to fetch msg values in this order.
*/
type = inboundMsgCreator.getChatMessageType(msg);
sender = inboundMsgCreator.getChatMessageSender(msg);
msgText = inboundMsgCreator.getChatMessageText(msg);
if (type == SimpleChatMessageTypes.BADTYPE) {
errorMessage("Message received in wrong format ! ");
return;
}
scp.newMessage(sender, type, msgText);
}
/*
* END INTERFACE MessageListener
*/
/*
* Popup the SimpleChatDialog to query the user for the chat user
* name and chat topic.
*/
private void queryForChatNames() {
if (scd == null) {
scd = new SimpleChatDialog(frame);
connectB = scd.getConnectButton();
connectB.addActionListener(this);
cancelB = scd.getCancelButton();
cancelB.addActionListener(this);
}
scd.setChatUserName(name);
scd.setChatTopicName(topicName);
scd.show();
}
/*
* Performs the actual chat connect.
* The createChatSession() method does the real work
* here, creating:
* Connection
* Session
* Topic
* MessageConsumer
* MessageProducer
*/
private void doConnect() {
if (connectedToChatSession())
return;
outgoingMsgCreator = getMessageCreator(outgoingMsgType);
if (createChatSession(topicName) == false) {
errorMessage("Unable to create Chat session. " +
"Please verify a broker is running");
return;
}
setConnectedToChatSession(true);
connectItem.setEnabled(false);
disconnectItem.setEnabled(true);
scp.setUserName(name);
scp.setDestName(topicName);
scp.setMsgType(outgoingMsgTypeString);
scp.setHostName(hostName);
scp.setEnabled(true);
}
/*
* Disconnects from chat session.
* destroyChatSession() performs the JMS cleanup.
*/
private void doDisconnect() {
if (!connectedToChatSession())
return;
destroyChatSession();
setConnectedToChatSession(false);
connectItem.setEnabled(true);
disconnectItem.setEnabled(false);
scp.setEnabled(false);
}
/*
* These methods set/return a flag that indicates
* whether the application is currently involved in
* a chat session.
*/
private void setConnectedToChatSession(boolean b) {
connected = b;
}
private boolean connectedToChatSession() {
return (connected);
}
/*
* Exit application. Does some cleanup if
* necessary.
*/
private void exit() {
doDisconnect();
System.exit(0);
}
/*
* Create the application GUI.
*/
private void initGui() {
frame = new Frame("Simple Chat");
frame.addWindowListener(this);
MenuBar menubar = createMenuBar();
frame.setMenuBar(menubar);
scp = new SimpleChatPanel();
scp.setUserName(name);
scp.setDestName(topicName);
scp.setHostName(hostName);
sendB = scp.getSendButton();
sendB.addActionListener(this);
frame.add(scp);
frame.pack();
frame.setVisible(true);
scp.setEnabled(false);
}
/*
* Create menubar for application.
*/
private MenuBar createMenuBar() {
MenuBar mb = new MenuBar();
Menu chatMenu;
chatMenu = (Menu) mb.add(new Menu("Chat"));
connectItem = (MenuItem) chatMenu.add(new MenuItem("Connect ..."));
disconnectItem = (MenuItem) chatMenu.add(new MenuItem("Disconnect"));
clearItem = (MenuItem) chatMenu.add(new MenuItem("Clear Messages"));
exitItem = (MenuItem) chatMenu.add(new MenuItem("Exit"));
disconnectItem.setEnabled(false);
connectItem.addActionListener(this);
disconnectItem.addActionListener(this);
clearItem.addActionListener(this);
exitItem.addActionListener(this);
return (mb);
}
/*
* Send message using text that is currently in the SimpleChatPanel
* object. The text message is obtained via scp.getMessage()
*
* An object of type ChatObjMessage is created containing the typed
* text. A JMS ObjectMessage is used to encapsulate this ChatObjMessage
* object.
*/
private void sendNormalMessage() {
Message msg;
if (!connectedToChatSession()) {
errorMessage("Cannot send message: Not connected to chat session!");
return;
}
try {
msg = outgoingMsgCreator.createChatMessage(session,
name,
SimpleChatMessageTypes.NORMAL,
scp.getMessage());
msgProducer.send(msg);
scp.setMessage("");
scp.requestFocus();
} catch (Exception ex) {
errorMessage("Caught exception while sending NORMAL message: " + ex);
}
}
/*
* Send a message to the chat session to inform people
* we just joined the chat.
*/
private void sendJoinMessage() {
Message msg;
try {
msg = outgoingMsgCreator.createChatMessage(session,
name,
SimpleChatMessageTypes.JOIN,
null);
msgProducer.send(msg);
} catch (Exception ex) {
errorMessage("Caught exception while sending JOIN message: " + ex);
}
}
/*
* Send a message to the chat session to inform people
* we are leaving the chat.
*/
private void sendLeaveMessage() {
Message msg;
try {
msg = outgoingMsgCreator.createChatMessage(session,
name,
SimpleChatMessageTypes.LEAVE,
null);
msgProducer.send(msg);
} catch (Exception ex) {
errorMessage("Caught exception while sending LEAVE message: " + ex);
}
}
/*
* JMS initialization.
* This is simply creating the ConnectionFactory.
*/
private void initJms(String args[]) {
/* XXX: chg for JMS1.1 to use BasicConnectionFactory for non-JNDI useage
* remove --- Use BasicConnectionFactory directly - no JNDI
*/
try {
connectionFactory
= new com.sun.messaging.ConnectionFactory();
} catch (Exception e) {
errorMessage("Caught Exception: " + e);
}
}
/*
* Create "chat session". This involves creating:
* Connection
* Session
* Topic
* MessageConsumer
* MessageProducer
*/
private boolean createChatSession(String topicStr) {
try {
/*
* Create the connection...
*
*/
connection = connectionFactory.createConnection();
/*
* Not transacted
* Auto acknowledegement
*/
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic(topicStr);
msgProducer = session.createProducer(topic);
/*
* Non persistent delivery
*/
msgProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
msgConsumer = session.createConsumer(topic);
msgConsumer.setMessageListener(this);
connection.start();
sendJoinMessage();
return true;
} catch (Exception e) {
errorMessage("Caught Exception: " + e);
e.printStackTrace();
return false;
}
}
/*
* Destroy/close "chat session".
*/
private void destroyChatSession() {
try {
sendLeaveMessage();
msgConsumer.close();
msgProducer.close();
session.close();
connection.close();
topic = null;
msgConsumer = null;
msgProducer = null;
session = null;
connection = null;
} catch (Exception e) {
errorMessage("Caught Exception: " + e);
}
}
/*
* Display error. Right now all we do is dump to
* stderr.
*/
private void errorMessage(String s) {
System.err.println(s);
}
}
/**
* This class provides the bulk of the UI:
* sendMsgTA TextArea for typing messages to send
* msgsTA TextArea for displaying messages in chat
* sendB Send button for activating a message "Send".
*
* ...and various labels to indicate the chat topic name,
* the user name, and host name.
*
*/
class SimpleChatPanel extends Panel implements SimpleChatMessageTypes {
private String destName,
userName,
msgType,
hostName;
private Button sendB;
private Label destLabel, userLabel, msgTypeLabel, msgsLabel,
sendMsgLabel;
private TextArea msgsTA;
private TextArea sendMsgTA;
/**
* SimpleChatPanel constructor
*/
public SimpleChatPanel() {
init();
}
/**
* Set the chat username
* @param userName Chat userName
*/
public void setUserName(String userName) {
this.userName = userName;
userLabel.setText("User Id: " + userName);
sendB.setLabel("Send Message as " + userName);
}
/**
* Set the chat hostname. This is pretty much
* the host that the router is running on.
* @param hostName Chat hostName
*/
public void setHostName(String hostName) {
this.hostName = hostName;
}
/**
* Sets the topic name.
* @param destName Chat topic name
*/
public void setDestName(String destName) {
this.destName = destName;
destLabel.setText("Topic: " + destName);
}
public void setMsgType(String msgType) {
this.msgType = msgType;
msgTypeLabel.setText("Outgoing Msg Type: " + msgType);
}
/**
* Returns the "Send" button.
*/
public Button getSendButton() {
return(sendB);
}
/**
* Clears the chat message text area.
*/
public void clear() {
msgsTA.setText("");
}
/**
* Appends the passed message to the chat message text area.
* @param msg Message to display
*/
public void newMessage(String sender, int type, String text) {
switch (type) {
case NORMAL:
msgsTA.append(sender + ": " + text + "\n");
break;
case JOIN:
msgsTA.append("*** " + sender + " has joined chat session\n");
break;
case LEAVE:
msgsTA.append("*** " + sender + " has left chat session\n");
break;
default:
}
}
/**
* Sets the string to display on the chat message textarea
* @param s String to display
*/
public void setMessage(String s) {
sendMsgTA.setText(s);
}
/**
* Returns the contents of the chat message textarea
*/
public String getMessage() {
return (sendMsgTA.getText());
}
/*
* Init chat panel GUI elements.
*/
private void init() {
Panel dummyPanel;
setLayout(new BorderLayout(0, 0));
destLabel = new Label("Topic:");
userLabel = new Label("User Id: ");
msgTypeLabel = new Label("Outgoing Msg Type:");
dummyPanel = new Panel();
dummyPanel.setLayout(new BorderLayout(0, 0));
dummyPanel.add("North", destLabel);
dummyPanel.add("Center", userLabel);
dummyPanel.add("South", msgTypeLabel);
add("North", dummyPanel);
dummyPanel = new Panel();
dummyPanel.setLayout(new BorderLayout(0, 0));
msgsLabel = new Label("Messages in chat:");
msgsTA = new TextArea(15, 40);
msgsTA.setEditable(false);
dummyPanel.add("North", msgsLabel);
dummyPanel.add("Center", msgsTA);
add("Center", dummyPanel);
dummyPanel = new Panel();
dummyPanel.setLayout(new BorderLayout(0, 0));
sendMsgLabel = new Label("Type Message:");
sendMsgTA = new TextArea(5, 40);
sendB = new Button("Send Message");
dummyPanel.add("North", sendMsgLabel);
dummyPanel.add("Center", sendMsgTA);
dummyPanel.add("South", sendB);
add("South", dummyPanel);
}
}
/**
* Dialog for querying the chat user name and chat topic.
*
*/
class SimpleChatDialog extends Dialog {
public final static int MSG_TYPE_UNDEFINED = -1;
public final static int MSG_TYPE_OBJECT = 0;
public final static int MSG_TYPE_TEXT = 1;
public final static int MSG_TYPE_MAP = 2;
public final static int MSG_TYPE_BYTES = 3;
public final static int MSG_TYPE_STREAM = 4;
private TextField nameF, topicF;
private Choice msgTypeChoice;
private Button connectB, cancelB;
/**
* SimpleChatDialog constructor.
* @param f Parent frame.
*/
public SimpleChatDialog(Frame f) {
super(f, "Simple Chat: Connect information", true);
init();
setResizable(false);
}
/**
* Return "Connect" button
*/
public Button getConnectButton() {
return (connectB);
}
/**
* Return "Cancel" button
*/
public Button getCancelButton() {
return (cancelB);
}
/**
* Return chat user name entered.
*/
public String getChatUserName() {
if (nameF == null)
return (null);
return (nameF.getText());
}
/**
* Set chat user name.
* @param s chat user name
*/
public void setChatUserName(String s) {
if (nameF == null)
return;
nameF.setText(s);
}
/**
* Set chat topic
* @param s chat topic
*/
public void setChatTopicName(String s) {
if (topicF == null)
return;
topicF.setText(s);
}
/**
* Return chat topic
*/
public String getChatTopicName() {
if (topicF == null)
return (null);
return (topicF.getText());
}
/*
* Get message type
*/
public int getMsgType() {
if (msgTypeChoice == null)
return (MSG_TYPE_UNDEFINED);
return (msgTypeChoice.getSelectedIndex());
}
public String getMsgTypeString() {
if (msgTypeChoice == null)
return (null);
return (msgTypeChoice.getSelectedItem());
}
/*
* Init GUI elements.
*/
private void init() {
Panel p, dummyPanel, labelPanel, valuePanel;
GridBagLayout labelGbag, valueGbag;
GridBagConstraints labelConstraints, valueConstraints;
Label chatNameLabel, chatTopicLabel,
msgTypeLabel;
int i, j;
p = new Panel();
p.setLayout(new BorderLayout());
dummyPanel = new Panel();
dummyPanel.setLayout(new BorderLayout());
/***/
labelPanel = new Panel();
labelGbag = new GridBagLayout();
labelConstraints = new GridBagConstraints();
labelPanel.setLayout(labelGbag);
j = 0;
valuePanel = new Panel();
valueGbag = new GridBagLayout();
valueConstraints = new GridBagConstraints();
valuePanel.setLayout(valueGbag);
i = 0;
chatNameLabel = new Label("Chat User Name:", Label.RIGHT);
chatTopicLabel = new Label("Chat Topic:", Label.RIGHT);
msgTypeLabel = new Label("Outgoing Msg Type:", Label.RIGHT);
labelConstraints.gridx = 0;
labelConstraints.gridy = j++;
labelConstraints.weightx = 1.0;
labelConstraints.weighty = 1.0;
labelConstraints.anchor = GridBagConstraints.EAST;
labelGbag.setConstraints(chatNameLabel, labelConstraints);
labelPanel.add(chatNameLabel);
labelConstraints.gridy = j++;
labelGbag.setConstraints(chatTopicLabel, labelConstraints);
labelPanel.add(chatTopicLabel);
labelConstraints.gridy = j++;
labelGbag.setConstraints(msgTypeLabel, labelConstraints);
labelPanel.add(msgTypeLabel);
nameF = new TextField(20);
topicF = new TextField(20);
msgTypeChoice = new Choice();
msgTypeChoice.insert("ObjectMessage", MSG_TYPE_OBJECT);
msgTypeChoice.insert("TextMessage", MSG_TYPE_TEXT);
msgTypeChoice.insert("MapMessage", MSG_TYPE_MAP);
msgTypeChoice.insert("BytesMessage", MSG_TYPE_BYTES);
msgTypeChoice.insert("StreamMessage", MSG_TYPE_STREAM);
msgTypeChoice.select(MSG_TYPE_STREAM);
valueConstraints.gridx = 0;
valueConstraints.gridy = i++;
valueConstraints.weightx = 1.0;
valueConstraints.weighty = 1.0;
valueConstraints.anchor = GridBagConstraints.WEST;
valueGbag.setConstraints(nameF, valueConstraints);
valuePanel.add(nameF);
valueConstraints.gridy = i++;
valueGbag.setConstraints(topicF, valueConstraints);
valuePanel.add(topicF);
valueConstraints.gridy = i++;
valueGbag.setConstraints(msgTypeChoice, valueConstraints);
valuePanel.add(msgTypeChoice);
dummyPanel.add("West", labelPanel);
dummyPanel.add("Center", valuePanel);
/***/
p.add("North", dummyPanel);
dummyPanel = new Panel();
connectB = new Button("Connect");
cancelB = new Button("Cancel");
dummyPanel.add(connectB);
dummyPanel.add(cancelB);
p.add("South", dummyPanel);
add(p);
pack();
}
}
interface SimpleChatMessageTypes {
public static int JOIN = 0;
public static int NORMAL = 1;
public static int LEAVE = 2;
public static int BADTYPE = -1;
}
interface SimpleChatMessageCreator {
public Message createChatMessage(Session session, String sender,
int type, String text);
public boolean isUsable(Message msg);
public int getChatMessageType(Message msg);
public String getChatMessageSender(Message msg);
public String getChatMessageText(Message msg);
}
class SimpleChatTextMessageCreator implements
SimpleChatMessageCreator, SimpleChatMessageTypes {
private static String MSG_SENDER_PROPNAME = "SIMPLECHAT_MSG_SENDER";
private static String MSG_TYPE_PROPNAME = "SIMPLECHAT_MSG_TYPE";
public Message createChatMessage(Session session, String sender,
int type, String text) {
TextMessage txtMsg = null;
try {
txtMsg = session.createTextMessage();
txtMsg.setStringProperty(MSG_SENDER_PROPNAME, sender);
txtMsg.setIntProperty(MSG_TYPE_PROPNAME, type);
txtMsg.setText(text);
} catch (Exception ex) {
System.err.println("Caught exception while creating message: " + ex);
}
return (txtMsg);
}
public boolean isUsable(Message msg) {
if (msg instanceof TextMessage) {
return (true);
}
return (false);
}
public int getChatMessageType(Message msg) {
int type = BADTYPE;
try {
TextMessage txtMsg = (TextMessage)msg;
type = txtMsg.getIntProperty(MSG_TYPE_PROPNAME);
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (type);
}
public String getChatMessageSender(Message msg) {
String sender = null;
try {
TextMessage txtMsg = (TextMessage)msg;
sender = txtMsg.getStringProperty(MSG_SENDER_PROPNAME);
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (sender);
}
public String getChatMessageText(Message msg) {
String text = null;
try {
TextMessage txtMsg = (TextMessage)msg;
text = txtMsg.getText();
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (text);
}
}
class SimpleChatObjMessageCreator implements
SimpleChatMessageCreator, SimpleChatMessageTypes {
public Message createChatMessage(Session session, String sender,
int type, String text) {
ObjectMessage objMsg = null;
ChatObjMessage sMsg;
try {
objMsg = session.createObjectMessage();
sMsg = new ChatObjMessage(sender, type, text);
objMsg.setObject(sMsg);
} catch (Exception ex) {
System.err.println("Caught exception while creating message: " + ex);
}
return (objMsg);
}
public boolean isUsable(Message msg) {
try {
ChatObjMessage sMsg = getSimpleChatMessage(msg);
if (sMsg == null) {
return (false);
}
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (true);
}
public int getChatMessageType(Message msg) {
int type = BADTYPE;
try {
ChatObjMessage sMsg = getSimpleChatMessage(msg);
if (sMsg != null) {
type = sMsg.getType();
}
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (type);
}
public String getChatMessageSender(Message msg) {
String sender = null;
try {
ChatObjMessage sMsg = getSimpleChatMessage(msg);
if (sMsg != null) {
sender = sMsg.getSender();
}
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (sender);
}
public String getChatMessageText(Message msg) {
String text = null;
try {
ChatObjMessage sMsg = getSimpleChatMessage(msg);
if (sMsg != null) {
text = sMsg.getMessage();
}
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (text);
}
private ChatObjMessage getSimpleChatMessage(Message msg) {
ObjectMessage objMsg;
ChatObjMessage sMsg = null;
if (!(msg instanceof ObjectMessage)) {
System.err.println("SimpleChatObjMessageCreator: Message received not of type ObjectMessage!");
return (null);
}
objMsg = (ObjectMessage)msg;
try {
sMsg = (ChatObjMessage)objMsg.getObject();
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (sMsg);
}
}
class SimpleChatMapMessageCreator implements
SimpleChatMessageCreator, SimpleChatMessageTypes {
private static String MAPMSG_SENDER_PROPNAME = "SIMPLECHAT_MAPMSG_SENDER";
private static String MAPMSG_TYPE_PROPNAME = "SIMPLECHAT_MAPMSG_TYPE";
private static String MAPMSG_TEXT_PROPNAME = "SIMPLECHAT_MAPMSG_TEXT";
public Message createChatMessage(Session session, String sender,
int type, String text) {
MapMessage mapMsg = null;
try {
mapMsg = session.createMapMessage();
mapMsg.setInt(MAPMSG_TYPE_PROPNAME, type);
mapMsg.setString(MAPMSG_SENDER_PROPNAME, sender);
mapMsg.setString(MAPMSG_TEXT_PROPNAME, text);
} catch (Exception ex) {
System.err.println("Caught exception while creating message: " + ex);
}
return (mapMsg);
}
public boolean isUsable(Message msg) {
if (msg instanceof MapMessage) {
return (true);
}
return (false);
}
public int getChatMessageType(Message msg) {
int type = BADTYPE;
try {
MapMessage mapMsg = (MapMessage)msg;
type = mapMsg.getInt(MAPMSG_TYPE_PROPNAME);
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (type);
}
public String getChatMessageSender(Message msg) {
String sender = null;
try {
MapMessage mapMsg = (MapMessage)msg;
sender = mapMsg.getString(MAPMSG_SENDER_PROPNAME);
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (sender);
}
public String getChatMessageText(Message msg) {
String text = null;
try {
MapMessage mapMsg = (MapMessage)msg;
text = mapMsg.getString(MAPMSG_TEXT_PROPNAME);
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (text);
}
}
class SimpleChatBytesMessageCreator implements
SimpleChatMessageCreator, SimpleChatMessageTypes {
public Message createChatMessage(Session session, String sender,
int type, String text) {
BytesMessage bytesMsg = null;
try {
byte b[];
bytesMsg = session.createBytesMessage();
bytesMsg.writeInt(type);
/*
* Write length of sender and text strings
*/
b = sender.getBytes();
bytesMsg.writeInt(b.length);
bytesMsg.writeBytes(b);
if (text != null) {
b = text.getBytes();
bytesMsg.writeInt(b.length);
bytesMsg.writeBytes(b);
} else {
bytesMsg.writeInt(0);
}
} catch (Exception ex) {
System.err.println("Caught exception while creating message: " + ex);
}
return (bytesMsg);
}
public boolean isUsable(Message msg) {
if (msg instanceof BytesMessage) {
return (true);
}
return (false);
}
public int getChatMessageType(Message msg) {
int type = BADTYPE;
try {
BytesMessage bytesMsg = (BytesMessage)msg;
type = bytesMsg.readInt();
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (type);
}
public String getChatMessageSender(Message msg) {
String sender = null;
sender = readSizeFetchString(msg);
return (sender);
}
public String getChatMessageText(Message msg) {
String text = null;
text = readSizeFetchString(msg);
return (text);
}
private String readSizeFetchString(Message msg) {
String stringData = null;
try {
BytesMessage bytesMsg = (BytesMessage)msg;
int length, needToRead;
byte b[];
length = bytesMsg.readInt();
if (length == 0) {
return ("");
}
b = new byte [length];
/*
* Loop to keep reading until all the bytes are read in
*/
needToRead = length;
while (needToRead > 0) {
byte tmpBuf[] = new byte [needToRead];
int ret = bytesMsg.readBytes(tmpBuf);
if (ret > 0) {
for (int i=0; i < ret; ++i) {
b[b.length - needToRead +i] = tmpBuf[i];
}
needToRead -= ret;
}
}
stringData = new String(b);
} catch (Exception ex) {
System.err.println("Caught exception: " + ex);
}
return (stringData);
}
}
class SimpleChatStreamMessageCreator implements
SimpleChatMessageCreator, SimpleChatMessageTypes {
public Message createChatMessage(Session session, String sender,
int type, String text) {
StreamMessage streamMsg = null;
try {
byte b[];
streamMsg = session.createStreamMessage();
streamMsg.writeInt(type);
streamMsg.writeString(sender);
if (text == null) {
text = "";
}
streamMsg.writeString(text);
} catch (Exception ex) {
System.err.println("Caught exception while creating message: " + ex);
}
return (streamMsg);
}
public boolean isUsable(Message msg) {
if (msg instanceof StreamMessage) {
return (true);
}
return (false);
}
public int getChatMessageType(Message msg) {
int type = BADTYPE;
try {
StreamMessage streamMsg = (StreamMessage)msg;
type = streamMsg.readInt();
} catch (Exception ex) {
System.err.println("getChatMessageType(): Caught exception: " + ex);
}
return (type);
}
public String getChatMessageSender(Message msg) {
String sender = null;
try {
StreamMessage streamMsg = (StreamMessage)msg;
sender = streamMsg.readString();
} catch (Exception ex) {
System.err.println("getChatMessageSender(): Caught exception: " + ex);
}
return (sender);
}
public String getChatMessageText(Message msg) {
String text = null;
try {
StreamMessage streamMsg = (StreamMessage)msg;
text = streamMsg.readString();
} catch (Exception ex) {
System.err.println("getChatMessageText(): Caught exception: " + ex);
}
return (text);
}
}
/**
* Object representing a message sent by chat application.
* We use this class and wrap a javax.jms.ObjectMessage
* around it instead of using a javax.jms.TextMessage
* because a simple string is not sufficient. We want
* be able to to indicate that a message is one of these
* types:
* join message ("Hi, I just joined")
* regular message (For regular chat messages)
* leave message ("Bye, I"m leaving")
*
*/
class ChatObjMessage implements java.io.Serializable, SimpleChatMessageTypes {
private int type = NORMAL;
private String sender,
message;
/**
* ChatObjMessage constructor. Construct a message with the given
* sender and message.
* @param sender Message sender
* @param type Message type
* @param message The message to send
*/
public ChatObjMessage(String sender, int type, String message) {
this.sender = sender;
this.type = type;
this.message = message;
}
/**
* Returns message sender.
*/
public String getSender() {
return (sender);
}
/**
* Returns message type
*/
public int getType() {
return (type);
}
/**
* Sets the message string
* @param message The message string
*/
public void setMessage(String message) {
this.message = message;
}
/**
* Returns the message string
*/
public String getMessage() {
return (message);
}
}
This example illustrates how JMS (Java Message Service) API can be used in a Java applet
/*
* @(#)MQApplet.java 1.1 10/10/03
*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license
* to use, modify and redistribute this software in source and binary
* code form, provided that i) this copyright notice and license
* appear on all copies of the software; and ii) Licensee does not
* utilize the software in a manner which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE
* SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS
* BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
* HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING
* OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line
* control of aircraft, air traffic, aircraft navigation or aircraft
* communications; or in the design, construction, operation or
* maintenance of any nuclear facility. Licensee represents and
* warrants that it will not use or redistribute the Software for such
* purposes.
*/
================================================================================
@(#)README 1.6 03/22/05
================================================================================
JMS Applet example
Description
-----------
This example illustrates how JMS API can be used in a Java applet.
MQApplet is a simple chat applet. It can be used with any Java enabled
browser.
Files
-----
MQApplet.java Source file for this example.
mqapplet.html HTML Source file for the applet.
README This file.
build.xml Build rules (for Jakarta Ant).
Configuring the environment
---------------------------
To recompile or run this example, you may need to modify the build.xml
file. Please change the value of the "libdir" property as appropriate.
It should point to the directory that contains the "imq.jar" and
"jms.jar" files.
Building the example
--------------------
* Set the JAVA_HOME environment variable to point to the JDK.
* Simply run the Jakarta ant build tool to build the applet.
The applet compilation process is a bit different from the typical
standalone Message Queue clients. It needs to do the following things -
* Compile MQApplet.java into MQApplet.class
* Bundle MQApplet.class into a jar file -> mqapplet.jar
* Copy the imq.jar and jms.jar files to a local directory.
* Generate a self signed certificate using keytool.
* Sign mqapplet.jar, imq.jar and jms.jar using this certificate.
Applets must be signed if they need to do anything non-trivial.
Otherwise you will get security exceptions at runtime.
Running the example applet
--------------------------
The build script places all the files necessary for running this
applet into a new directory named "install". Copy all the contents of
this directory somewhere under a web server"s document root. This
includes -
* mqapplet.html
* Signed Jar files : mqapplet.jar, imq.jar, jms.jar
After this, the applet can be run by simply pointing the browser to
the "mqapplet.html" file.
After the applet is loaded, the web browser (Java plugin) should open
a dialog box asking for permission to run a signed applet. Click on
the "Yes" button.
When the applet starts running it will not automatically connect to
a Message Queue broker. Please specify the broker"s address and click
on the "Connect" button.
Running as a standalone application
-----------------------------------
The MQApplet.class(build/MQApplet.class) can also be used as a
standalone application. It presents the same UI as the applet. To run
this example as a standalone application, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer"s Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:/opt/sun/mq/share/lib/imq.jar:.
Note that it is assumed that the above export command is run on
BASH shell
After setting the CLASSPATH, simply run -
java MQApplet
Obviously, you don"t need the signed jar files for running as
a standalone application.
/*
* @(#)MQApplet.java 1.1 10/10/03
*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license
* to use, modify and redistribute this software in source and binary
* code form, provided that i) this copyright notice and license
* appear on all copies of the software; and ii) Licensee does not
* utilize the software in a manner which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
* LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE
* SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS
* BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
* HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING
* OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line
* control of aircraft, air traffic, aircraft navigation or aircraft
* communications; or in the design, construction, operation or
* maintenance of any nuclear facility. Licensee represents and
* warrants that it will not use or redistribute the Software for such
* purposes.
*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.jms.*;
/**
* This is a simple chat applet that uses JMS APIs. It uses publish
* subscribe model. It can also be run as a standalone application.
*/
public class MQApplet extends JApplet
implements ActionListener, ExceptionListener, MessageListener {
private static boolean DEBUG = Boolean.getBoolean("mqapplet.debug");
private static String TRANSPORT;
static {
TRANSPORT = System.getProperty("mqapplet.transport");
if (TRANSPORT == null)
TRANSPORT = "";
}
private JPanel mainPanel;
private StatusPanel statusBar;
private JTextField urlField;
private JTextField hostField, portField;
private JTextField addrField;
private JTextArea txArea, rxArea;
JButton connectButton, exitButton, clearButton, sendButton;
private boolean createExitButton = false;
public void init() {
initGUI();
initJMS();
}
public void destroy() {
shutdownJMS();
shutdownGUI();
}
private void enableExit() {
createExitButton = true;
}
private void initGUI() {
// The application window contains the "mainPanel" container
// and a status bar.
Container content = getContentPane();
// Create the mainPanel container. It holds all the UI
// components...
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
content.add("Center", mainPanel);
// Create the status bar..
statusBar = new StatusPanel();
content.add("South", statusBar);
//
// Now start populating mainPanel...
//
// dialogPanel contains JMS configuration and the connect
// button.
JPanel dialogPanel = new JPanel();
dialogPanel.setLayout(
new BoxLayout(dialogPanel, BoxLayout.Y_AXIS));
dialogPanel.setBorder(
createMyBorder("JMS Connection Properties..."));
JPanel dummyPanel;
if (TRANSPORT.equalsIgnoreCase("http")) {
dummyPanel = new JPanel();
dummyPanel.setLayout(new BoxLayout(dummyPanel, BoxLayout.X_AXIS));
dummyPanel.add(new JLabel("imqConnectionURL : "));
urlField = new JTextField("http://");
dummyPanel.add(urlField);
dialogPanel.add(dummyPanel);
}
else if (TRANSPORT.equalsIgnoreCase("tcp")) {
dummyPanel = new JPanel();
dummyPanel.setLayout(new BoxLayout(dummyPanel, BoxLayout.X_AXIS));
dummyPanel.add(new JLabel("imqBrokerHostName : "));
hostField = new JTextField("localhost");
dummyPanel.add(hostField);
dialogPanel.add(dummyPanel);
dummyPanel = new JPanel();
dummyPanel.setLayout(new BoxLayout(dummyPanel, BoxLayout.X_AXIS));
dummyPanel.add(new JLabel("imqBrokerHostPort : "));
portField = new JTextField("7676");
dummyPanel.add(portField);
dialogPanel.add(dummyPanel);
}
else {
dummyPanel = new JPanel();
dummyPanel.setLayout(new BoxLayout(dummyPanel, BoxLayout.X_AXIS));
dummyPanel.add(new JLabel("imqAddressList : "));
addrField = new JTextField("mq://localhost:7676");
dummyPanel.add(addrField);
dialogPanel.add(dummyPanel);
}
dummyPanel = new JPanel();
dummyPanel.setLayout(new BoxLayout(dummyPanel, BoxLayout.X_AXIS));
connectButton = new JButton();
connectButton.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(3, 0, 3, 3),
connectButton.getBorder()));
connectButton.addActionListener(this);
setConnectButton("Connect");
dummyPanel.add(connectButton);
if (createExitButton) {
exitButton = new JButton("Exit");
exitButton.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(3, 3, 3, 3),
exitButton.getBorder()));
exitButton.addActionListener(this);
dummyPanel.add(exitButton);
}
dialogPanel.add(dummyPanel);
JPanel messagePanel = new JPanel();
messagePanel.setLayout(new GridLayout(2, 1));
dummyPanel = new JPanel();
dummyPanel.setLayout(new BoxLayout(dummyPanel, BoxLayout.Y_AXIS));
dummyPanel.setBorder(createMyBorder("Received messages "));
rxArea = new JTextArea();
rxArea.setEditable(false);
JScrollPane spane = new JScrollPane(rxArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
dummyPanel.add(spane);
clearButton = new JButton("Clear");
clearButton.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(3, 3, 3, 3),
clearButton.getBorder()));
clearButton.addActionListener(this);
dummyPanel.add(clearButton);
messagePanel.add(dummyPanel);
dummyPanel = new JPanel();
dummyPanel.setLayout(new BoxLayout(dummyPanel, BoxLayout.Y_AXIS));
dummyPanel.setBorder(createMyBorder("Send message "));
txArea = new JTextArea();
txArea.setEditable(true);
spane = new JScrollPane(txArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
dummyPanel.add(spane);
sendButton = new JButton("Send");
sendButton.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(3, 3, 3, 3),
sendButton.getBorder()));
sendButton.addActionListener(this);
dummyPanel.add(sendButton);
messagePanel.add(dummyPanel);
mainPanel.add("North", dialogPanel);
mainPanel.add("Center", messagePanel);
}
private void initJMS() {
}
private void shutdownGUI() {
remove(mainPanel);
mainPanel = null;
}
private void shutdownJMS() {
doDisconnect();
}
public void processEvent(AWTEvent e) {
if (e.getID() == Event.WINDOW_DESTROY) {
System.exit(0);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Connect")) {
if (TRANSPORT.equalsIgnoreCase("http")) {
String us = urlField.getText();
statusBar.setStatusLine("Connecting to " + us + "...");
initHTTPConnectionFactory(us);
}
else if (TRANSPORT.equalsIgnoreCase("tcp")) {
String h = hostField.getText();
String p = portField.getText();
statusBar.setStatusLine("Connecting to " + h + ":" + p + "...");
initTCPConnectionFactory(h, p);
}
else {
String addr = addrField.getText();
statusBar.setStatusLine("Connecting to " + addr + "...");
initConnectionFactory(addr);
}
doConnect();
}
if (e.getActionCommand().equals("Disconnect")) {
statusBar.setStatusLine("Disconnecting...");
doDisconnect();
statusBar.setStatusLine("Connection closed.");
}
if (e.getActionCommand().equals("Send")) {
String ss = txArea.getText();
doSend(ss);
txArea.setText(null);
}
if (e.getActionCommand().equals("Clear")) {
rxArea.setText(null);
}
if (e.getActionCommand().equals("Exit")) {
doDisconnect();
System.exit(0);
}
}
public void updateRxArea(String s) {
rxArea.append(s);
}
public void enableConnectButton() {
setConnectButton("Connect");
}
public void enableDisconnectButton() {
setConnectButton("Disconnect");
}
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
MessageConsumer msgConsumer = null;
MessageProducer msgProducer = null;
TextMessage textMessage = null;
public void initHTTPConnectionFactory(String s) {
try {
if (connectionFactory == null) {
connectionFactory = (ConnectionFactory)
new com.sun.messaging.ConnectionFactory();
}
// Provider specific code start.
com.sun.messaging.ConnectionFactory cf =
(com.sun.messaging.ConnectionFactory) connectionFactory;
cf.setProperty(
com.sun.messaging.ConnectionConfiguration.imqConnectionType,
"HTTP");
cf.setProperty(
com.sun.messaging.ConnectionConfiguration.imqConnectionURL,
s);
// Provider specific code end.
}
catch (JMSException e) {
updateRxArea("initHTTPConnectionFactory : " + e.toString() + "\n");
e.printStackTrace();
if (e.getLinkedException() != null)
e.getLinkedException().printStackTrace();
}
}
public void initTCPConnectionFactory(String h, String p) {
try {
if (connectionFactory == null) {
connectionFactory = (ConnectionFactory)
new com.sun.messaging.ConnectionFactory();
}
// Provider specific code start.
com.sun.messaging.ConnectionFactory cf =
(com.sun.messaging.ConnectionFactory) connectionFactory;
// Set imqAddressList property.
((com.sun.messaging.ConnectionFactory)cf).setProperty(
com.sun.messaging.ConnectionConfiguration.imqAddressList,
new StringBuffer().append("mq://").append(h).append(
":").append(p).append("/jms").toString());
// Provider specific code end.
}
catch (JMSException e) {
updateRxArea("initTCPConnectionFactory : " + e.toString() + "\n");
e.printStackTrace();
if (e.getLinkedException() != null)
e.getLinkedException().printStackTrace();
}
}
public void initConnectionFactory(String a) {
if (connectionFactory == null) {
connectionFactory = (ConnectionFactory)
new com.sun.messaging.ConnectionFactory();
}
try {
// Provider specific code start.
com.sun.messaging.ConnectionFactory cf =
(com.sun.messaging.ConnectionFactory) connectionFactory;
cf.setProperty(
com.sun.messaging.ConnectionConfiguration.imqAddressList,
a);
// Provider specific code end.
}
catch (JMSException e) {
updateRxArea("initConnectionFactory : " + e.toString() + "\n");
e.printStackTrace();
if (e.getLinkedException() != null)
e.getLinkedException().printStackTrace();
}
}
public void doConnect() {
try {
connection = connectionFactory.createConnection();
connection.setExceptionListener(this);
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic("MQChatAppletTopic");
msgConsumer = session.createConsumer(topic);
msgConsumer.setMessageListener(this);
msgProducer = session.createProducer(topic);
textMessage = session.createTextMessage();
statusBar.setStatusLine("Connected");
enableDisconnectButton();
}
catch (JMSException e) {
updateRxArea("doConnect : " + e.toString() + "\n");
statusBar.setStatusLine("Unable to connect.");
e.printStackTrace();
if (e.getLinkedException() != null)
e.getLinkedException().printStackTrace();
}
}
public void doSend(String s) {
if (msgProducer == null) {
statusBar.setStatusLine("Not connected.");
return;
}
try {
textMessage.setText(s);
msgProducer.send(textMessage);
}
catch (JMSException e) {
updateRxArea("doSend : " + e.toString() + "\n");
e.printStackTrace();
}
}
public void doDisconnect() {
try {
if (connection != null)
connection.close();
}
catch (Exception e) {}
connection = null;
session = null;
topic = null;
msgConsumer = null;
msgProducer = null;
textMessage = null;
enableConnectButton();
}
public void onException(JMSException e) {
statusBar.setStatusLine("Connection lost : " + e.toString());
doDisconnect();
}
public void onMessage(Message m) {
try {
if (m instanceof TextMessage) {
String s = ((TextMessage) m).getText();
updateRxArea(s);
}
}
catch (JMSException e) {
e.printStackTrace();
updateRxArea("onMessage : " + e.toString() + "\n");
}
}
private void setConnectButton(String text) {
connectButton.setText(text);
connectButton.setActionCommand(text);
connectButton.invalidate();
connectButton.validate();
mainPanel.repaint();
}
private javax.swing.border.Border createMyBorder(String title) {
javax.swing.border.Border inner =
BorderFactory.createLineBorder(Color.black);
if (title != null)
inner = BorderFactory.createTitledBorder(inner, title);
javax.swing.border.Border outer =
BorderFactory.createEmptyBorder(3, 3, 3, 3);
return BorderFactory.createCompoundBorder(outer, inner);
}
public void cleanupAndExit() {
destroy();
System.exit(0);
}
public static MQApplet mq = null;
public static void mainWindowClosed() {
mq.cleanupAndExit();
}
public static void main(String []args) {
JFrame f = new JFrame("MQApplet");
f.setDefaultCloseOperation(f.DO_NOTHING_ON_CLOSE);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
mainWindowClosed();
}
});
mq = new MQApplet();
mq.enableExit();
mq.init();
mq.start();
f.getContentPane().add("Center", mq);
f.setSize(600, 600);
f.show();
}
class StatusPanel extends JPanel {
private JLabel label = null;
public StatusPanel() {
setLayout(new BorderLayout());
setBorder(BorderFactory.createLoweredBevelBorder());
label = new JLabel();
int size = label.getFont().getSize();
label.setFont(new Font("Serif", Font.PLAIN, size));
add("West", label);
setStatusLine("Ready");
}
public void setStatusLine(String statusLine) {
if (statusLine == null)
statusLine = "";
label.setText(statusLine);
invalidate();
validate();
repaint();
}
}
}
/*
* EOF
*/
This example is a simple JMS client application
/*
* @(#)HelloWorldMessage.java 1.8 05/03/09
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
================================================================================
@(#)README 1.7 03/22/05
================================================================================
HelloWorldMessage example
Description
-----------
This example is a simple JMS client application. It is the companion
example to the "Quick Start Tutorial" in the Sun Java(tm) System Message
Queue Developer"s Guide. This application sends and receives a "Hello World"
message via a Queue destination. This example does not use JNDI to
lookup administered objects.
Files
-----
HelloWorldMessage.java Source file for this example.
*.class Prebuilt Java class files for this example.
README This file.
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer"s Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac HelloWorldMessage.java
Running the example
-------------------
Run the following:
java HelloWorldMessage
You should see the following output:
Sending Message: Hello World
Read Message: Hello World
/*
* @(#)HelloWorldMessage.java 1.8 05/03/09
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/**
* The HelloWorldMessage class consists only of a main method, which sends
* a message to a queue and then receives the message from the queue.
* <p>
* This example is used in the "Quick Start Tutorial" of the Sun Java(tm)
* System Message Queue Developer"s Guide to illustrate a very simple JMS
* client.
* The line comments associate the lines of code with the steps in the tutorial.
*
* @version 1.8 05/03/09
*/
//Step 1:
//Import the JMS API classes.
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.MessageProducer;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Message;
import javax.jms.TextMessage;
//Import the classes to use JNDI.
import javax.naming.*;
import java.util.*;
public class HelloWorldMessage {
/**
* Main method.
*
* @param args not used
*
*/
public static void main(String[] args) {
try {
ConnectionFactory myConnFactory;
Queue myQueue;
/*
* The following code uses the JNDI File System Service Provider
* to lookup() Administered Objects that were stored in the
* Administration Console Tutorial in the Administrator"s Guide
*
* The following code (in this comment block replaces the
* statements in Steps 2 and 5 of this example.
*
****
String MYCF_LOOKUP_NAME = "MyConnectionFactory";
String MYQUEUE_LOOKUP_NAME = "MyQueue";
Hashtable env;
Context ctx = null;
env = new Hashtable();
// Store the environment variable that tell JNDI which initial context
// to use and where to find the provider.
// For use with the File System JNDI Service Provider
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
// On Unix, use file:///tmp instead of file:///C:/Temp
env.put(Context.PROVIDER_URL, "file:///C:/Temp");
// Create the initial context.
ctx = new InitialContext(env);
// Lookup my connection factory from the admin object store.
// The name used here here must match the lookup name
// used when the admin object was stored.
myConnFactory = (javax.jms.ConnectionFactory) ctx.lookup(MYCF_LOOKUP_NAME);
// Lookup my queue from the admin object store.
// The name I search for here must match the lookup name used when
// the admin object was stored.
myQueue = (javax.jms.Queue)ctx.lookup(MYQUEUE_LOOKUP_NAME);
****
*
*/
//Step 2:
//Instantiate a Sun Java(tm) System Message Queue ConnectionFactory
//administered object.
//This statement can be eliminated if the JNDI code above is used.
myConnFactory = new com.sun.messaging.ConnectionFactory();
//Step 3:
//Create a connection to the Sun Java(tm) System Message Queue Message
//Service.
Connection myConn = myConnFactory.createConnection();
//Step 4:
//Create a session within the connection.
Session mySess = myConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//Step 5:
//Instantiate a Sun Java(tm) System Message Queue Destination
//administered object.
//This statement can be eliminated if the JNDI code above is used.
myQueue = new com.sun.messaging.Queue("world");
//Step 6:
//Create a message producer.
MessageProducer myMsgProducer = mySess.createProducer(myQueue);
//Step 7:
//Create and send a message to the queue.
TextMessage myTextMsg = mySess.createTextMessage();
myTextMsg.setText("Hello World");
System.out.println("Sending Message: " + myTextMsg.getText());
myMsgProducer.send(myTextMsg);
//Step 8:
//Create a message consumer.
MessageConsumer myMsgConsumer = mySess.createConsumer(myQueue);
//Step 9:
//Start the Connection created in step 3.
myConn.start();
//Step 10:
//Receive a message from the queue.
Message msg = myMsgConsumer.receive();
//Step 11:
//Retreive the contents of the message.
if (msg instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) msg;
System.out.println("Read Message: " + txtMsg.getText());
}
//Step 12:
//Close the session and connection resources.
mySess.close();
myConn.close();
} catch (Exception jmse) {
System.out.println("Exception occurred : " + jmse.toString());
jmse.printStackTrace();
}
}
}