I have been looking for some documentation/example for checking if a dynamically created topic exist and if it does, how to get the subscriber count for the topic.
I use following code for sending out message to a topic -
jmsTemplate.send(destination, new MessageCreator() {
#Override
public Message createMessage(Session session) throws JMSException {
TextMessage message = session.createTextMessage();
message.setText(commandStr);
return message;
}
});
This code seems to create the topic and publish message to topic.
I need to check if the topic exists before creating it.
Check if the topic have any subscriber.
Thanks in advance
i was able to find the solution to (1) problem (Hope this helps)-
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
ActiveMQConnection connection = (ActiveMQConnection)connectionFactory.createConnection();
connection.start();
DestinationSource ds = connection.getDestinationSource();
Set<ActiveMQTopic> topics = ds.getTopics();
To get the destination names, as you did it is correct, you can do it by JMX too specifically to get statistical information like subscriber count ...
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.TopicViewMBean;
public class JMXGetDestinationInfos {
public static void main(String[] args) throws Exception {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
Map<String, String[]> env = new HashMap<>();
String[] creds = { "admin", "admin" };
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();
ObjectName activeMq = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");
BrokerViewMBean mbean = MBeanServerInvocationHandler.newProxyInstance(conn, activeMq, BrokerViewMBean.class,
true);
for (ObjectName name : mbean.getTopics()) {
if (("YOUR_TOPIC_NAME".equals(name.getKeyProperty("destinationName")))) {
TopicViewMBean topicMbean = MBeanServerInvocationHandler.newProxyInstance(conn, name,
TopicViewMBean.class, true);
System.out.println(topicMbean.getConsumerCount());
}
}
}
}
or
import java.util.Set;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.advisory.DestinationSource;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
public class AdvisorySupportGetAllDestinationsNames {
public static void main(String[] args) throws JMSException {
Connection conn = null;
try {
ConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
conn = cf.createConnection();
conn.start();
DestinationSource destinationSource = ((ActiveMQConnection) conn).getDestinationSource();
Set<ActiveMQQueue> queues = destinationSource.getQueues();
Set<ActiveMQTopic> topics = destinationSource.getTopics();
System.out.println(queues);
System.out.println(topics);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
}
}
}
}
}
UPDATE
You can use AdvisorySupport.getConsumerAdvisoryTopic()
Note that the consumer start/stop advisory messages also have a
consumerCount header to indicate the number of active consumers on the
destination when the advisory message was sent.
Related
I am looking for reference where I can get simple program to send a SNMP trap to Apache Kafka topic using Apache Camel.
Please help me if someone can explain the it using simple java program.
My RouteBuilder configuration
import org.apache.camel.builder.RouteBuilder;
public class SimpleRouteBuilder extends RouteBuilder{
#Override
public void configure() throws Exception {
String topicName = "topic=first_topic";
String kafkaServer = "kafka:localhost:9092";
String zooKeeperHost = "zookeeperHost=localhost&zookeeperPort=2181";
String serializerClass = "serializerClass=kafka.serializer.StringEncoder";
String toKafka = new StringBuilder().append(kafkaServer).append("?").append(topicName).append("&")
.append(zooKeeperHost).append("&").append(serializerClass).toString();
System.out.println(toKafka);
from("snmp:127.0.0.1:161?protocol=udp&type=POLL&oids=1.3.6.1.2.1.1.5.0").split().tokenize("\n").to(toKafka);
}
}
Main Method
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.snmp4j.Snmp;
public class MainApp {
public static void main(String[] args) {
SimpleRouteBuilder routeBuilder = new SimpleRouteBuilder();
CamelContext ctx = new DefaultCamelContext();
try {
ctx.addRoutes(routeBuilder);
ctx.start();
Thread.sleep(5 * 60 * 1000);
ctx.stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
I was in wrong direction. The write direction is as below -
Create a Trap sender program.
Create Trap receiver/listener program.
Inside Trap receiver or listener, receive trap and send it to Apache Kafka topic through Apache camel.
POM.XML
add below dependencies -
camel-core
snmp4j
camel-kafka
Trap Sender Program
package <>;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import java.util.Date;
public class Trapsender {
public static final String community = "public";
public static final String Oid = ".1.3.6.1.2.1.1.8";
public static final String ipAddress = "127.0.0.1";
public static final int port = 162;
public static void main(String[] args) {
Trapsender trapv3 = new Trapsender();
trapv3.sendTrap_Version3();
}
public void sendTrap_Version3() {
try {
// Create Transport Mapping
TransportMapping transport = new DefaultUdpTransportMapping();
transport.listen();
// Create Target
CommunityTarget cTarget = new CommunityTarget();
cTarget.setCommunity(new OctetString(community));
cTarget.setVersion(SnmpConstants.version2c);
cTarget.setAddress(new UdpAddress(ipAddress + "/" + port));
cTarget.setRetries(2);
cTarget.setTimeout(10000);
// Create PDU for V3
PDU pdu = new PDU();
pdu.setType(PDU.TRAP);
// need to specify the system up time
pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new OctetString(new Date().toString())));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(Oid)));
pdu.add(new VariableBinding(new OID(Oid), new OctetString("Major")));
// Send the PDU
Snmp snmp = new Snmp(transport);
System.out.println("Sending V2 Trap... Check Wheather NMS is Listening or not? ");
ResponseEvent send = snmp.send(pdu, cTarget);
snmp.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Receiver Trap with Apache Camel
package <>;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.snmp4j.*;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.security.Priv3DES;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.TransportIpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.AbstractTransportMapping;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import java.io.IOException;
public class Trapreceiver implements CommandResponder {
public static CamelContext ctx=null;
public static ProducerTemplate producer=null;
public static void main(String[] args) {
Trapreceiver snmp4jTrapReceiver = new Trapreceiver();
SimpleRouteBuilder routeBuilder = new SimpleRouteBuilder();
ctx = new DefaultCamelContext();
producer = ctx.createProducerTemplate();
try {
ctx.addRoutes(routeBuilder);
ctx.start();
}
catch (Exception e) {
e.printStackTrace();
}
// producer.sendBody("direct:start", snmp);
try {
snmp4jTrapReceiver.listen(new UdpAddress("localhost/162"), producer);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Trap Listner
*/
public synchronized void listen(TransportIpAddress address, ProducerTemplate producer)
throws IOException {
AbstractTransportMapping transport;
if (address instanceof TcpAddress) {
transport = new DefaultTcpTransportMapping((TcpAddress) address);
} else {
transport = new DefaultUdpTransportMapping((UdpAddress) address);
}
ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);
MessageDispatcher mDispathcher = new MultiThreadedMessageDispatcher(
threadPool, new MessageDispatcherImpl());
// add message processing models
mDispathcher.addMessageProcessingModel(new MPv1());
mDispathcher.addMessageProcessingModel(new MPv2c());
// add all security protocols
SecurityProtocols.getInstance().addDefaultProtocols();
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
// Create Target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
Snmp snmp = new Snmp(mDispathcher, transport);
snmp.addCommandResponder(this);
transport.listen();
System.out.println("Listening on " + address);
try {
this.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
/**
* This method will be called whenever a pdu is received on the given port
* specified in the listen() method
*/
public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
System.out.println("Received PDU...");
PDU pdu = cmdRespEvent.getPDU();
if (pdu != null) {
System.out.println("Trap Type = " + pdu.getType());
System.out.println("Variables = " + pdu.getVariableBindings());
producer.sendBody("direct:start","Variables = " + pdu.getVariableBindings() );
}
}
}
I have to test a specific scenario by closing the Active-MQ consumer socket without killing the java client process and Active-MQ server.
what is the best way to close specific socket between JAVA client and Active-MQ queue?
maybe by calling org.apache.activemq.ActiveMQMessageConsumer.close() or org.apache.activemq.ActiveMQConnection.close() to close all sessions of consumers/producers
UPDATE
you can use VisualVM and call stop method,
Please consider that if your client is using failover he will reconnect automatically
or by code like below
to close 1 consumer by ID or RemoteAddress
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.apache.activemq.broker.jmx.ConnectionViewMBean;
public class JMXCloseConsumer {
public static void main(String[] args) throws Exception {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
Map<String, String[]> env = new HashMap<>();
String[] creds = { "admin", "admin" };
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();
ObjectName conName = new ObjectName(
"org.apache.activemq:type=Broker,brokerName=localhost,connector=clientConnectors,connectorName=openwire,connectionViewType=clientId,connectionName=*");
Set connections = conn.queryNames(conName, null);
Object[] c = connections.toArray();
for (int s = 0; s < c.length; s++) {
ObjectName con = (ObjectName) c[s];
System.out.println(con.toString());
ConnectionViewMBean connectionView = MBeanServerInvocationHandler.newProxyInstance(conn, con,
ConnectionViewMBean.class, true);
String address = connectionView.getRemoteAddress();
System.out.println(address);
connectionView.stop();
}
}
}
to close all consumers by connector name
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.ConnectorViewMBean;
public class JMXCloseAllConsumers {
public static void main(String[] args) throws Exception {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
Map<String, String[]> env = new HashMap<>();
String[] creds = { "admin", "admin" };
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();
ObjectName activeMq = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");
BrokerViewMBean mbean = MBeanServerInvocationHandler.newProxyInstance(conn, activeMq, BrokerViewMBean.class,
true);
Map<String, String> props = mbean.getTransportConnectors();
for (Iterator<?> iter = props.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String value1 = props.get(name);
System.out.println(value1);
ObjectName connector = new ObjectName(
"org.apache.activemq:type=Broker,brokerName=localhost,connector=clientConnectors,connectorName="
+ name);
ConnectorViewMBean connectorViewMBean = MBeanServerInvocationHandler.newProxyInstance(conn, connector,
ConnectorViewMBean.class, true);
System.out.println(connectorViewMBean.connectionCount());
if (connectorViewMBean.connectionCount() > 0) {
connectorViewMBean.stop();
}
}
}
}
or
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.ConnectionViewMBean;
import org.apache.activemq.broker.jmx.ConnectorViewMBean;
public class JMXCloseAllConsumers {
public static void main(String[] args) throws Exception {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
Map<String, String[]> env = new HashMap<>();
String[] creds = { "admin", "admin" };
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();
ObjectName activeMq = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");
BrokerViewMBean mbean = MBeanServerInvocationHandler.newProxyInstance(conn, activeMq, BrokerViewMBean.class,
true);
Map<String, String> props = mbean.getTransportConnectors();
for (Iterator<?> iter = props.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
System.out.println(name);
ObjectName connector = new ObjectName(
"org.apache.activemq:type=Broker,brokerName=localhost,connector=clientConnectors,connectorName="
+ name);
ConnectorViewMBean connectorViewMBean = MBeanServerInvocationHandler.newProxyInstance(conn, connector,
ConnectorViewMBean.class, true);
System.out.println(connectorViewMBean.connectionCount());
if (connectorViewMBean.connectionCount() > 0) {
ObjectName conName = new ObjectName(
"org.apache.activemq:type=Broker,brokerName=localhost,connector=clientConnectors,connectorName="
+ name + ",connectionViewType=clientId,connectionName=*");
Set connections = conn.queryNames(conName, null);
Object[] c = connections.toArray();
for (int s = 0; s < c.length; s++) {
ObjectName con = (ObjectName) c[s];
System.out.println(con.toString());
ConnectionViewMBean connectionView = MBeanServerInvocationHandler.newProxyInstance(conn, con,
ConnectionViewMBean.class, true);
String address = connectionView.getRemoteAddress();
System.out.println(address);
connectionView.stop();
}
connectorViewMBean.stop();
}
}
}
}
So I have a simple JMS app, using a topic, powered by activeMQ. It works, but only 1 message is being sent (even though I am writing more lines in the console and so trying to send more stuff).
When I check the web console of ActiveMq, only 1 message is being sent (I also get this message in the ReceiverTopic class)...Why is this happening?
Below you can see my sender code:
package topic;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class SenderTopic {
private ConnectionFactory factory = null;
private Connection connection = null;
private Session session = null;
private Destination destination = null;
private MessageProducer producer = null;
private boolean jmsInitialized = false;
public SenderTopic() {
}
private void initJMS() throws JMSException {
factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL);
connection = factory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = session.createTopic("SAMPLE_TOPIC");
producer = session.createProducer(destination);
jmsInitialized = true;
}
private void sendMessage(String message) {
if (!jmsInitialized) {
try {
initJMS();
sendTextMessage(message);
} catch (JMSException e) {
jmsInitialized = false;
e.printStackTrace();
}
}
}
private void sendTextMessage(String message) throws JMSException {
TextMessage textMessage = session.createTextMessage(message);
producer.send(textMessage);
}
public static void main(String[] args) throws IOException {
SenderTopic receiver = new SenderTopic();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String message = reader.readLine();
receiver.sendMessage(message);
}
}
}
Intially the value of jmsInitialized is false, so your if condition (!jmsInitialized) will be true.
On second call of sendMessage the value of jmsInitialized will be true and the if condition fails because you are using not on boolean value.
You can add a else condition with only call to sendTextMessage.
try out this
private void sendMessage(String message) {
try {
if (!jmsInitialized) {
initJMS();
sendTextMessage(message);
}else{
sendTextMessage(message);
}
} catch (JMSException e) {
jmsInitialized = false;
e.printStackTrace();
}
}
}
I am not able to receive notifications using HCATALOG using JMS. I wrote simple producer consumer program.
Apache MQ service is running in background. I am able to send simple text messages using ApacheMQ. But "markPartitionForEvent()" is not able to send event to consumer's "onMessage()" call.
I refered following link :
https://cwiki.apache.org/confluence/display/Hive/HCatalog+Notification
Please guide
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.thrift.TException;
import javax.jms.MessageConsumer;
import javax.management.*;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.PartitionEventType;
import org.apache.hadoop.hive.metastore.api.Partition;
import org.apache.hcatalog.common.HCatConstants;
import java.util.Properties;
import javax.jms.*;
import javax.jdo.*;
import javax.naming.*;
import java.io.*;
import java.io.InputStreamReader;
import java.util.*;
import javax.jms.MessageConsumer;
import org.slf4j.LoggerFactory;
import org.datanucleus.api.jdo.*;
import javax.jdo.metadata.JDOMetadata;
import org.datanucleus.store.rdbms.RDBMSStoreManager;
import org.datanucleus.properties.PropertyStore;
import org.datanucleus.store.AbstractStoreManager;
import org.apache.hadoop.hive.metastore.api.Table;
class Consumer implements MessageListener
{
public void start(){
try
{
HiveConf hiveConf;
ActiveMQConnectionFactory connFac = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection conn = connFac.createConnection();
conn.start();
hiveConf = new HiveConf(Consumer.class);
HiveMetaStoreClient msc = new HiveMetaStoreClient(hiveConf);
Table table = msc.getTable("mydb","myTbl");
table.getParameters().put(HCatConstants.HCAT_MSGBUS_TOPIC_NAME, "TOPIC"+ ".HCATALOG");
System.out.println("TABLE = " + table.toString());
Map<String,String> map = table.getParameters();
System.out.println("MAP= " + map.toString());
String fetchTopic = map.get(HCatConstants.HCAT_MSGBUS_TOPIC_NAME);
System.out.println("fetchTopic = " + fetchTopic);
String topicName = msc.getTable("mydb",
"mytbl").getParameters().get(HCatConstants.HCAT_MSGBUS_TOPIC_NAME);
System.out.println("TOPICNAME = " + topicName);
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
if (session == null)
System.out.println("NULL");
System.out.println(session.toString());
Destination hcatTopic = session.createTopic(fetchTopic);
MessageConsumer consumer = session.createConsumer(hcatTopic);
consumer.setMessageListener(this);
}
catch(Exception e){
System.out.println("ERROR");
e.printStackTrace();
}
}
#Override
public void onMessage(Message message){
try
{
if(message.getStringProperty(HCatConstants.HCAT_EVENT).equals(HCatConstants.HCAT_PARTITION_DONE_EVENT)){
MapMessage mapMsg = (MapMessage)message;
Enumeration<String> keys = mapMsg.getMapNames();
while(keys.hasMoreElements())
{
String key = keys.nextElement();
System.out.println(key + " : " + mapMsg.getString(key));
}
System.out.println("Message: "+message);
}
}
catch(Exception e){
System.out.println("ERROR");
}
}
};
class Producer extends Thread
{
private HiveConf hiveConf;
public Producer()
{
}
#Override
public void run() {
try
{
hiveConf = new HiveConf(this.getClass());
HiveMetaStoreClient msc = new HiveMetaStoreClient(hiveConf);
HashMap<String,String> partMap = new HashMap<String, String>();
partMap.put("date","20110711");
partMap.put("date","20110712");
partMap.put("date","20110714");
while(true)
{
msc.markPartitionForEvent("mydb", "mytbl", partMap, PartitionEventType.LOAD_DONE);
Thread.sleep(1000);
}
}
catch(Exception e){
System.out.println("ERROR");
}
}
};
I am new to JMS, after a long re search i googled out a code to connect to JMS and post a msg.
The problem is i need to post the message in a remote queue, But i am not sure how to establish connection to it and post the message.
SERVER TYPE : TIBCO EMS
SERVER HOST : **.*****.net
PORT : *
**USername : user
passsword : user123
Queue : *.*....Order.Management..1
I would like to establish connection, post a simple msg and retrieve it back.
Kindly help! thanks in advance
CODE WHICH I GOT FROM INTERNET
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class emm {
// Defines the JNDI context factory.
public final static String JNDI_FACTORY="com.tibco.tibjms.naming.TibjmsInitialContextFactory";
// Defines the JMS context factory.
public final static String JMS_FACTORY="jms/TestConnectionFactory";
// Defines the queue.
public final static String QUEUE="CPW.GBR.POR.Public.Request.Order.Management.UpdateProvisioningStatus.1";
private QueueConnectionFactory qconFactory;
private ConnectionFactory conFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;
/**
* Creates all the necessary objects for sending
* messages to a JMS queue.
*
* #param ctx JNDI initial context
* #param queueName name of queue
* #exception NamingException if operation cannot be performed
* #exception JMSException if JMS fails to initialize due to internal error
*/
public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
}
/**
* Sends a message to a JMS queue.
*
* #param message message to be sent
* #exception JMSException if JMS fails to send message due to internal error
*/
public void send(String message) throws JMSException {
msg.setText(message);
qsender.send(msg);
}
/**
* Closes JMS objects.
* #exception JMSException if JMS fails to close objects due to internal error
*/
public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}
/** main() method.
*
* #param args WebLogic Server URL
* #exception Exception if operation fails
*/
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("Usage: java examples.jms.queue.QueueSend WebLogicURL");
return;
}
InitialContext ic = getInitialContext(args[0]);
emm qs = new emm();
qs.init(ic, QUEUE);
readAndSend(qs);
qs.close();
}
private static void readAndSend(emm qs)
throws IOException, JMSException
{
BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
String line=null;
boolean quitNow = false;
do {
System.out.print("Enter message (\"quit\" to quit): \n");
line = msgStream.readLine();
if (line != null && line.trim().length() != 0) {
qs.send(line);
System.out.println("JMS Message Sent: "+line+"\n");
quitNow = line.equalsIgnoreCase("quit");
}
} while (! quitNow);
}
private static InitialContext getInitialContext(String url)
throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
}
Finally from different sources i found the best possible to way for this.
This code will definitely work. I have tried this out and is running currently on my machine
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.*;
public class JMSExample {
static String serverUrl = "tcp://10.101.111.101:10001"; // values changed
static String userName = "user";
static String password = "pwd";
static QueueConnection connection;
static QueueReceiver queueReceiver;
static Queue queue;
static TextMessage message;
public static void sendTopicMessage(String topicName, String messageStr) {
Connection connection = null;
Session session = null;
MessageProducer msgProducer = null;
Destination destination = null;
try {
TextMessage msg;
System.out.println("Publishing to destination '" + topicName
+ "'\n");
ConnectionFactory factory = new com.tibco.tibjms.TibjmsConnectionFactory(
serverUrl);
connection = factory.createConnection(userName, password);
session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
destination = session.createQueue(topicName);
msgProducer = session.createProducer(null);
msg = session.createTextMessage();
msg.setStringProperty("SourceId", userName);
msg.setStringProperty("BusinessEvent", password);
msg.setText(messageStr);
msgProducer.send(destination, msg);
System.out.println("Published message: " + messageStr);
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws JMSException {
// TODO Auto-generated method stub
JMSExample.sendTopicMessage("***.***.***.**.**.Order.Management.***.1",
"Hi");
//System.out.println(getMessage());
}
As i mentioned some code for inspiration (SLIGHTLY improved your code. Not something i would want to see in production!)
// Use the domain-agnostic API
private Connection connection;ery
private Session session;
private MessageProducer producer;
private Queue queue;
public void init(Context ctx, String queueName) {
try {
ConnectionFactory cnf = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
queue = (Queue) ctx.lookup(queueName);
connection = cnf.createConnection("user", "user123");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer = session.createProducer(queue);
connection.start();
} catch (NamingException e) {
throw new RuntimeException(e);
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
And make your send like this (don't reuse the same Message object, but create a new one for each message you are sending)
public void send(String message) throws JMSException {
TextMessage msg = session.createTextMessage();
msg.setText(message);
producer.send(msg);
}
Put a try..finally around the code in your main method:
try {
readAndSend(qs);
} finally {
qs.close();
}
The code you are using is not very good (understatement). It is programmed too brittle for a production system. You should not use state the way this program does.
Also there is no need to use the domain specific JMS API. You can use the domain (queue/topic) agnostic one.
When you run the program pass in the JNDI URL for your TIBCO server.