How to create a simple JMS topic, publisher and subscriber in Oracle 10g

Posted by Steve Racanovic | Posted in , | Posted on 2:48 PM

1

In continuing from my previous updates about jms, this time I am writing a simple file persistence jms topic.

I am still using the same version OracleAS 10.1.3.2.0 as the JMS Provider.

1. Create the JMS destination. Run the following from $OH\j2ee\home:

java -jar admin_client.jar deployer:oc4j:opmn://sracanov-au.au.oracle.com:6007/JMS oc4jadmin welcome1 -addDestination -domain topic -name jmstopic -jndiLocation jms/MyJMSTopic -persistenceFile myjmstopic.txt

This will create a presistence file “myjmstopic.txt” to store the message. You can see the file by navigating to

$OH\j2ee\<instance_name>\persistence\<instance_name>_<group_name>_1

[sracanov@sracanov-au D]$ java -jar admin_client.jar deployer:oc4j:opmn://sracanov-au.au.oracle.com:6007/JMS oc4jadmin welcome1 -addDestination -domain topic -name jmstopic -jndiLocation jms/MyJMSTopic -persistenceFile myjmstopic.txt
Command was successful

2. Create the JMS connection factory. Run the following from $OH\j2ee\home:

java -jar admin_client.jar deployer:oc4j:opmn://sracanov-au.au.oracle.com:6007/JMS oc4jadmin welcome1 -addJMSConnectionFactory -domain topic -jndiLocation jms/MyJMSTCF

[sracanov@sracanov-au D]$ java -jar admin_client.jar deployer:oc4j:opmn://sracanov-au.au.oracle.com:6007/JMS oc4jadmin welcome1 -addJMSConnectionFactory -domain topic -jndiLocation jms/MyJMSTCF

3. We need to create 3 java classes. Once again, I am using Jdev to create my classes. So first I will create a new application and project.

I will need to make sure the follow libraries are including in the project:
· J2EE
· Apache Ant

4. Now create the publisher client:

package project1;

import java.util.Hashtable;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;


public class MyTopicPublisher {

public static void main(String[] args) {
final String topicName = "jms/MyJMSTopic";
final String topicConnectionFactoryName = "jms/MyJMSTCF";
final String oc4juser = "oc4jadmin";
final String oc4juserpassword = "welcome1";
final String urlProvider = "opmn:ormi://";
final String jmsProviderHost = "sracanov-au.au.oracle.com";
final String colon = ":";
final String opmnPort = "6007";
final String oc4jinstance = "OC4J_JMS";
final int NUMBER_OF_MESSAGES = 5;
TopicConnection topicConnection = null;
TopicConnectionFactory topicConnectionFactory = null;
Context jndiContext = null;
TopicSession topicSession = null;
Topic topic = null;
TopicPublisher topicPublisher = null;
MapMessage message = null;

/*
* Set the environment for a connection to the OC4J instance
*/
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"oracle.j2ee.rmi.RMIInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, oc4juser);
env.put(Context.SECURITY_CREDENTIALS, oc4juserpassword);
env.put(Context.PROVIDER_URL,
urlProvider + jmsProviderHost + colon + opmnPort + colon +
oc4jinstance + "/default");

/*
* Set the Context Object.
* Lookup the Topic Connection Factory.
* Lookup the JMS Destination.
*/
try {
jndiContext = new InitialContext(env);
topicConnectionFactory =
(TopicConnectionFactory)jndiContext.lookup(topicConnectionFactoryName);
topic = (Topic)jndiContext.lookup(topicName);
} catch (NamingException e) {
System.out.println("Lookup failed: " + e.toString());
System.exit(1);
}

/*
* Create connection.
* Create session from connection.
* Create publisher.
* Create text message.
* Send messages.
* Close connection.
*/
try {
topicConnection = topicConnectionFactory.createTopicConnection();
topicSession =
topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topicPublisher = topicSession.createPublisher(topic);
message = topicSession.createMapMessage();
for (int i = 0; i < NUMBER_OF_MESSAGES; i++) {
message.setStringProperty("from", "from@" + jmsProviderHost);
message.setStringProperty("to", "to@" + jmsProviderHost);
message.setStringProperty("subject",
"Topic Message " + (i + 1));
message.setStringProperty("content",
"Message " + (i + 1) + " in Topic: \"" +
topicName + "\"");
System.out.println("Publishing message: " +
message.getStringProperty("from"));
System.out.println("Publishing message: " +
message.getStringProperty("to"));
System.out.println("Publishing message: " +
message.getStringProperty("subject"));
System.out.println("Publishing message: " +
message.getStringProperty("content"));
topicPublisher.publish(message);
}
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
} finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {
System.out.println("Closing error: " + e.toString());
}
}
}
}
}

5. Now we need to create the message listener that will listen to meesages on map types:

package project1;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;

public class JMSTopicMapListener implements MessageListener {

public void onMessage(Message message) {
MapMessage msg = null;

try {
if (message instanceof MapMessage) {
msg = (MapMessage)message;
String from = msg.getStringProperty("from");
String to = msg.getStringProperty("to");
String subject = msg.getStringProperty("subject");
String content = msg.getStringProperty("content");
System.out.println("READING MESSAGE \n=============== \nFrom: " +
from + "\nTo: " + to + "\nSubject: " +
subject + "\nContent: " + content);
} else {
System.out.println("Wrong type");
}
} catch (JMSException e) {
System.out.println("JMSException in onMessage(): " + e.toString());
} catch (Throwable t) {
System.out.println("Exception in onMessage():" + t.getMessage());
}
}
}

6. Create the subscriber client:

package project1;

import javax.jms.*;

import javax.naming.*;

import java.util.Hashtable;

public class MyTopicSubscriber {

public static void main(String[] args) {
final String topicName = "jms/MyJMSTopic";
final String topicConnectionFactoryName = "jms/MyJMSTCF";
final String oc4juser = "oc4jadmin";
final String oc4juserpassword = "welcome1";
final String urlProvider = "opmn:ormi://";
final String jmsProviderHost = "sracanov-au.au.oracle.com";
final String colon = ":";
final String opmnPort = "6007";
final String oc4jinstance = "OC4J_JMS";
Context jndiContext = null;
TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
Topic topic = null;
TopicSubscriber topicSubscriber = null;
JMSTopicMapListener topicListener = null;

/*
* Set the environment for a connection to the OC4J instance
*/
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"oracle.j2ee.rmi.RMIInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, oc4juser);
env.put(Context.SECURITY_CREDENTIALS, oc4juserpassword);
env.put(Context.PROVIDER_URL,
urlProvider + jmsProviderHost + colon + opmnPort + colon +
oc4jinstance + "/default");

/*
* Set the Context Object.
* Lookup the Topic Connection Factory.
* Lookup the JMS Destination.
*/
try {
jndiContext = new InitialContext(env);
topicConnectionFactory =
(TopicConnectionFactory)jndiContext.lookup(topicConnectionFactoryName);
topic = (Topic)jndiContext.lookup(topicName);
} catch (NamingException e) {
System.out.println("Lookup failed: " + e.toString());
System.exit(1);
}

/*
* Create connection.
* Create session from connection; false means session is
* not transacted.
* Create subscriber.
* Register message listener (TextListener).
* Receive text messages from topic.
* Close connection.
*/
try {
topicConnection = topicConnectionFactory.createTopicConnection();
topicSession =
topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topicSubscriber = topicSession.createSubscriber(topic);
topicListener = new JMSTopicMapListener();
topicSubscriber.setMessageListener(topicListener);
topicConnection.start();
System.out.println("Subscripted to topic: \"" + topicName + "\"");
while (true) {
}
} catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
} finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {
System.out.println("Closing error: " + e.toString());
}
}
}
}
}

7. Ensure the follow Strings in the publisher and subcriber java class are set according to your environment:

final String topicName = "jms/MyJMSTopic";
final String topicConnectionFactoryName = "jms/MyJMSTCF";
final String oc4juser = "oc4jadmin";
final String oc4juserpassword = "welcome1";
final String urlProvider = "opmn:ormi://";
final String jmsProviderHost = "sracanov-au.au.oracle.com";
final String colon = ":";
final String opmnPort = "6007";
final String oc4jinstance = "JMS";

8. Run the subcriber class. The subscriber is waiting for message to be sent by the publisher. You will see the following message in the console.

Subscripted to topic: "jms/MyJMSTopic"


9. Run the publisher class. The following results in displayed in the publisher console:

Publishing message: from@sracanov-au.au.oracle.com
Publishing message: to@sracanov-au.au.oracle.com
Publishing message: Topic Message 1
Publishing message: Message 1 in Topic: "jms/MyJMSTopic"
Publishing message: from@sracanov-au.au.oracle.com
Publishing message: to@sracanov-au.au.oracle.com
Publishing message: Topic Message 2
Publishing message: Message 2 in Topic: "jms/MyJMSTopic"
Publishing message: from@sracanov-au.au.oracle.com
Publishing message: to@sracanov-au.au.oracle.com
Publishing message: Topic Message 3
Publishing message: Message 3 in Topic: "jms/MyJMSTopic"
Publishing message: from@sracanov-au.au.oracle.com
Publishing message: to@sracanov-au.au.oracle.com
Publishing message: Topic Message 4
Publishing message: Message 4 in Topic: "jms/MyJMSTopic"
Publishing message: from@sracanov-au.au.oracle.com
Publishing message: to@sracanov-au.au.oracle.com
Publishing message: Topic Message 5
Publishing message: Message 5 in Topic: "jms/MyJMSTopic"
Process exited with exit code 0.

10. Back in the subscriber console, the following message is displayed:

READING MESSAGE
===============
From: from@sracanov-au.au.oracle.com
To: to@sracanov-au.au.oracle.com
Subject: Topic Message 1
Content: Message 1 in Topic: "jms/MyJMSTopic"
READING MESSAGE
===============
From: from@sracanov-au.au.oracle.com
To: to@sracanov-au.au.oracle.com
Subject: Topic Message 2
Content: Message 2 in Topic: "jms/MyJMSTopic"
READING MESSAGE
===============
From: from@sracanov-au.au.oracle.com
To: to@sracanov-au.au.oracle.com
Subject: Topic Message 3
Content: Message 3 in Topic: "jms/MyJMSTopic"
READING MESSAGE
===============
From: from@sracanov-au.au.oracle.com
To: to@sracanov-au.au.oracle.com
Subject: Topic Message 4
Content: Message 4 in Topic: "jms/MyJMSTopic"
READING MESSAGE
===============
From: from@sracanov-au.au.oracle.com
To: to@sracanov-au.au.oracle.com
Subject: Topic Message 5
Content: Message 5 in Topic: "jms/MyJMSTopic"

Ensure you stop the subscriber client when done.

Comments (1)

Dear,

Please, how can I do this example using annotations? I tried, but when the container try to inject (DI) on @Resource(mappedName="jms/connectionFactory") ConnectionFactory connectionFactory

Connection conn = connectionFactory.createConnection(); the nullPointerException is threw!
There are any idea?
Thanks,
Leonardo
BRAZIL