JMS API cannot browse messages, IBM API can - java

My current application logic uses the depth of the a 'PROCESS' WMQ queue to determine if a job is being processed by an IIB9 workflow. If the workflow is processing a messages, the application wait till that workflow is over. Once the workflow is over, the 'PROCESS' queue will be emptied using GET operation and the application sends other messages in the sequence for processing. I am using JMS selectors to differentiate between multiple messages being processed parallelly by the workflow.
The issue is with determining the depth of the queue. JMS API is giving the depth as 0, while IBM API is giving the depth as 1(which is expected). Unfortunately, I cannot use IBM API as my logic using some complex messageselectors.
Has anyone seen this bizarre behaviour? Please note that the IIB9 workflow is in progress while the size check is being made. Is there a setting to be tweaked?
JMS Code (message selector removed for clarity):
public class QDepthJMS {
public static void main(String[] a) throws Exception {
MQConnectionFactory factory = new MQConnectionFactory();
factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
factory.setQueueManager("QM01");
factory.setHostName("10.10.98.15");
factory.setPort(1414);
factory.setChannel("Java.Clients");
MQConnection connection = (MQConnection) factory.createConnection();
connection.start();
MQSession session = (MQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("queue:///PROCESS");
MQQueueBrowser browser = (MQQueueBrowser) session.createBrowser(queue);
Enumeration<Message> msgs = browser.getEnumeration();
int count =0;
if (msgs.hasMoreElements()) {
msgs.nextElement();
++count;
}
System.out.println(count);
}
}
IBM API (Check MQ queue depth):
public class QDepth {
private final String host;
private final int port;
private final String channel;
private final String manager;
private final MQQueueManager qmgr;
public QDepth(String host, int port, String channel, String manager) throws MQException {
this.host = host;
this.port = port;
this.channel = channel;
this.manager = manager;
this.qmgr = createQueueManager();
}
public int depthOf(String queueName) throws MQException {
MQQueue queue = qmgr.accessQueue(queueName, MQC.MQOO_INQUIRE | MQC.MQOO_INPUT_AS_Q_DEF, null, null, null);
return queue.getCurrentDepth();
}
#SuppressWarnings("unchecked")
private MQQueueManager createQueueManager() throws MQException {
MQEnvironment.channel = channel;
MQEnvironment.port = port;
MQEnvironment.hostname = host;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
return new MQQueueManager(manager);
}
public static void main(String[] a) throws Exception {
QDepth qd = new QDepth("10.10.98.15, 1414, "Java.Clients", "QM01");
System.out.println(qd.depthOf("PROCESS"));
}
}

You are not comparing "like with like" - The IBM API queries the queue depth, ie how many messages are in the queue but the JMS API is browsing through the messages and counting them. There is a valid reason for them to be different - the usual cause is that someone has put a message under a unit of work (syncpoint) and it has not yet been committed - Therefore at the point you run the IBM API it will say there's 1 message on the queue (there is...) but it is not gettable / browseable as its not yet committed.
You can verify this using runmqsc (and probably the GUI) by runmqsc DIS QSTATUS and look at the UNCOM attribute - See http://www-01.ibm.com/support/docview.wss?uid=swg21636775

Related

How can I set expire time of queue message using ActiveMQ by Java Programming?

In this code, I am using setJMSExpiration(1000) for expire message of one second in queue from publisher side. But From Consumer Side, It is returning properly message after 1 second instead of null.
public class RegistrationPublisher extends Thread{
public void run() {
publisherQueue("Registration.Main.*");
}
public void publisherQueue(String server){
try {
String url="tcp://192.168.20.49:61616";
// Create a ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(server);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
String text = "Test";
TextMessage message = session.createTextMessage(text);
message.setJMSExpiration(1000);// For Expire message in one second
producer.send(message);
producer.close();
session.close();
connection.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) throws IOException{
RegistrationPublisher registrationPublisher=new RegistrationPublisher();
registrationPublisher.start();
}
}
You do this by configuring the JMS MessageProducer to do it for you via the send method that accepts a TTL or by calling setTimeToLive on the producer which adds the same TTL to all sent messages. The JMS APIs for the message version are clear that calling the setters on the message have no effect.
void setJMSExpiration(long expiration) throws JMSException
Sets the message's expiration value.
This method is for use by JMS providers only to set this field when a message is sent. This message cannot be used by clients to configure the expiration time of the message. This method is public to allow a JMS provider to set this field when sending a message whose implementation is not its own.
I first also thought that is was possible to set expiration directly on the message in the post-processor, but as Tim Bish said above, this is not the intended way to do it, and the value will get reset to 0 afterward. I couldn't access to the producer directly neither to set a time to live, because this object was in library org.springframework.jms (I was following this documentation).
One thing I could do was to set to time to live on the jmsTemplate:
import org.springframework.jms.core.JmsTemplate;
#Service
public class MyJmsServiceImpl implements MyJmsService {
#Inject
private JmsTemplate jmsTemplate;
private void convertAndSendToResponseQueue(String targetQueueName, String correlationid, Object message) {
// Set time to live
jmsTemplate.setExplicitQosEnabled(true);
jmsTemplate.setTimeToLive(5000);
jmsTemplate.convertAndSend(targetQueueName, message, new JmsResponsePostProcessor(correlationid));
}
}

Java JMS MessageListener onMessage running on some PCs but not others

I am seeking insights into this strange problem we are having with a Java software application. The application is downloaded from a web site and communicates
with a server on the internet using a JMS/JBOSS in a publish/subscribe model. At a high level, the problem is that on many of our Windows 7 PCs (64-Bit Win7 OS with JRE 1.7.0_51-b13 32 bit), the client application does not receive the messages sent from the server. The onMessage() method appears to not get invoked.
The frustrating bit is that on some of our PCs (which were deployed using Ghost hard drive image so theoretically should have identical configurations), the application does receive the messages - We can see onMessage() method is working as expected.
I am able to examine the TCP/IP traffic coming in to the PC and I can see the messages arriving from the server to the client's TCP/IP stack. But somehow there is something keeping the messages from triggering the Java onMessage handler.
Another really strange twist is that if we leave the client application running for maybe 20 minutes, suddenly it starts to receive messages (that is the onMessage() method gets triggered). Again we know it is getting messages all along from looking at the TCP/IP traffic.
The basic outline of the code we are using is shown below. I think it pretty much follows the example here1 and has most of the similar elements. Any suggestions for further debugging or exploration would be appreciated.
public class MyPubSub {
private static final String CONN_FACTORY_QUEUE = "jms/RemoteConnectionFactory";
private static final String QUEUE_A = "jms/queue/QueueA";
private static final String CONN_FACTORY_TOPIC = "jms/RemoteConnectionFactory";
private static final String USERNAME = "xyz";
private static final String PWD = "xyz123";
public static void main(String[] args)
{
String hostURL = "some_host_string_thing_here";
String remotingURL = "remote://"+hostURL+":4447";
// Establish context
Context ctx;
QueueConnectionFactory qcf = null;
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
p.put(Context.PROVIDER_URL, remotingURL);
p.put(Context.SECURITY_PRINCIPAL, USERNAME);
p.put(Context.SECURITY_CREDENTIALS, PWD);
ctx = new InitialContext(p);
// Set up Queue
QueueConnectionFactory qcf = null;
QueueConnection qconn = null;
QueueSession qsession = null;
Queue queueA = null;
QueueReceiver qrecv = null;
qcf = (QueueConnectionFactory)ctx.lookup(CONN_FACTORY_QUEUE);
qconn = qcf.createQueueConnection(USERNAME, PWD);
qsession = qconn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
messageProducer = qsession.createProducer(queueA);
// Set up Topic
TopicConnectionFactory tcf;
TopicConnection connA = null;
TopicSession sessionA = null;
Topic topicA = null;
TopicSubscriber recvA;
tcf = (TopicConnectionFactory)ctx.lookup(CONN_FACTORY_TOPIC);
topicA = (Topic)ctx.lookup(TOPICA);
connA = tcf.createTopicConnection(USERNAME, PWD);
connA.setExceptionListener(new ExceptionListenerImpl());
sessionA = connA.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
messageProducerA = sessionA.createProducer(getJmsDestination(TOPICA));
recvA = sessionA.createSubscriber(topicA);
// Associate the MessageListener ExListenerA()
recvA.setMessageListener(new ExListenerA());
// Start
connA.start();
}
public class ExListenerA implements MessageListener {
public void onMessage(Message msg) {
TextMessage oo = (TextMessage) msg;
System.out.println("Got message" + oo.getText());
}
}
}
After setting the message listener the connection is not started. That could have caused the problem.

Grizzly 2.2.19 SSL sample code not working

Very little documentation, above what exists in the sample code is currently available for Grizzly 2.2 and I have found this to be most difficult to navigate as it relates to SSL implementation. I am desperately in need of some guidance in this area. After reviewing my code to determine what I need to post in order to pose a complete question, I realized it might be most beneficial to first cement the basics.
Below are three classes provided by the Grizzly project in order to demonstrate a sample implementation of Grizzly's SSL capabilities. Besides the removal of comments, the code is identical to the 2.2.19 released code base as maintained in git at git://java.net/grizzly~git and also available here.
The git repository also provides the referenced truststore and keystore.
EchoFilter:
public class EchoFilter extends BaseFilter{
#Override
public NextAction handleRead(FilterChainContext ctx)throws IOException {
//|Peer address is used for non-connected UDP Connection
final Object peerAddress = ctx.getAddress();
final Object message = ctx.getMessage();
ctx.write(peerAddress, message, null);
return ctx.getStopAction();
}
}
SSLEchoServer:
public class SSLEchoServer{
public static final String HOST = "localhost";
public static final int PORT = 7777;
public static void main(String[] args) throws IOException{
//|Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
//|Add TransportFilter, which is responsible for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
//|Initialize and add SSLFilter
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
filterChainBuilder.add(new SSLFilter(serverConfig, clientConfig));
//|Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
//|Use the plain EchoFilter
filterChainBuilder.add(new EchoFilter());
//|Create TCP transport
final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
//|Set filterchain as a Transport Processor
transport.setProcessor(filterChainBuilder.build());
try{
//|Binding transport to start listen on certain host and port
transport.bind(HOST, PORT);
//|Start the transport
transport.start();
System.out.println("Press any key to stop the server...");
System.in.read();
}finally{
System.out.println("Stopping transport...");
//|Stop the transport
transport.stop();
System.out.println("Stopped transport...");
}
}
private static SSLEngineConfigurator initializeSSL(){
//|Initialize SSLContext configuration
SSLContextConfigurator sslContextConfig = new SSLContextConfigurator();
//|Set key store
ClassLoader cl = SSLEchoServer.class.getClassLoader();
URL cacertsUrl = cl.getResource("ssltest-cacerts.jks");
if(cacertsUrl != null){
sslContextConfig.setTrustStoreFile(cacertsUrl.getFile());
sslContextConfig.setTrustStorePass("changeit");
}
//|Set trust store
URL keystoreUrl = cl.getResource("ssltest-keystore.jks");
if(keystoreUrl != null){
sslContextConfig.setKeyStoreFile(keystoreUrl.getFile());
sslContextConfig.setKeyStorePass("changeit");
}
//|Create SSLEngine configurator
return new SSLEngineConfigurator(sslContextConfig.createSSLContext(), false, false, false);
}
}
SSLEchoClient:
public class SSLEchoClient{
private static final String MESSAGE = "Hello World!";
public static void main(String[] args) throws IOException{
//|Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
//|Add TransportFilter, which is responsible for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
//|Initialize and add SSLFilter
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
final SSLFilter sslFilter = new SSLFilter(serverConfig, clientConfig);
filterChainBuilder.add(sslFilter);
//|Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
//|Add Filter, which will send a greeting message and check the result
filterChainBuilder.add(new SendMessageFilter(sslFilter));
//|Create TCP transport
final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
//|Set filterchain as a Transport Processor
transport.setProcessor(filterChainBuilder.build());
try{
//|Start the transport
transport.start();
//|Perform async. connect to the server
transport.connect(SSLEchoServer.HOST, SSLEchoServer.PORT);
System.out.println("Press any key to stop the client...");
System.in.read();
}finally{
System.out.println("Stopping transport...");
//|Stop the transport
transport.stop();
System.out.println("Stopped transport...");
}
}
private static class SendMessageFilter extends BaseFilter{
private final SSLFilter sslFilter;
public SendMessageFilter(SSLFilter sslFilter){
this.sslFilter = sslFilter;
}
#Override
#SuppressWarnings("unchecked")
public NextAction handleConnect(FilterChainContext ctx) throws IOException{
final Connection connection = ctx.getConnection();
//|Execute async SSL handshake
sslFilter.handshake(connection, new EmptyCompletionHandler<SSLEngine>(){
//|Once SSL handshake will be completed - send greeting message
#Override
public void completed(SSLEngine result){
//|Here we send String directly
connection.write(MESSAGE);
}
});
return ctx.getInvokeAction();
}
#Override
public NextAction handleRead(FilterChainContext ctx) throws IOException{
//|The received message is String
final String message = (String) ctx.getMessage();
//|Check the message
if(MESSAGE.equals(message)){
System.out.println("Got echo message: \"" + message + "\"");
}else{
System.out.println("Got unexpected echo message: \"" + message + "\"");
}
return ctx.getStopAction();
}
}
private static SSLEngineConfigurator initializeSSL(){
//|Initialize SSLContext configuration
SSLContextConfigurator sslContextConfig = new SSLContextConfigurator();
//|Set key store
ClassLoader cl = SSLEchoClient.class.getClassLoader();
URL cacertsUrl = cl.getResource("ssltest-cacerts.jks");
if(cacertsUrl != null){
sslContextConfig.setTrustStoreFile(cacertsUrl.getFile());
sslContextConfig.setTrustStorePass("changeit");
}
//|Set trust store
URL keystoreUrl = cl.getResource("ssltest-keystore.jks");
if(keystoreUrl != null){
sslContextConfig.setKeyStoreFile(keystoreUrl.getFile());
sslContextConfig.setKeyStorePass("changeit");
}
//|Create SSLEngine configurator
return new SSLEngineConfigurator(sslContextConfig.createSSLContext(), false, false, false);
}
}
When executing:
Run SSLEchoServer:
Press any key to stop the server...
Run SSLEchoClient:
Press any key to stop the client...
Question:
What is this code supposed to accomplish or demonstrate? Beyond the console output you see above, this code does nothing on my end.
In reviewing the code, my expectation was that the client was supposed start its TCP transport and connect it to the server. In the process of that connection being made, the SendMessageFilter previously added to the filter stream will execute its handleConnect() method, which I confirmed does execute. But, this code never executes the connection.write(MESSAGE) statement.
It's clear the intention here is to execute the write() method after the handshake thread completes, but it doesn't appear to do so, and in examining the handshake() method in SSLFilter class in grizzly-framework-2.2.19, I was also unable to determine where the overridden parent completed() method is even defined.
Can anyone lend some insight to whether this disconnect is due to my lack of understanding something here or if it is potentially a bug in the sample implementation provided by Grizzly? I believe clearing this up will go a long way to further my understanding here. Thank you in advance!

I send a scheduled message to activemq broker but two message shown in web console

I wrote a simple ActiveMQ client program for produce a message as following:
public static void main(String[] args) throws Throwable
{
final ActiveMQConnectionFactory conFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
final QueueConnection connection = conFactory.createQueueConnection();
final Session session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
final Destination destination = new ActiveMQQueue("MJ_SAF");
final MessageProducer producer = session.createProducer(destination);
Message message = session.createTextMessage("test");
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 20);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 1);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 1);
producer.send(message);
}
when this program executed I expect a message stored in scheduled part of ActiveMQ and after 20 second send for MJ_SAF queue but when I connect to web consol saw following result:
stored two messages at MJ_SAF and it's not correct but when I normally send message (without scheduling), I see a message in web console.
public static void main(String[] args) throws Throwable
{
final ActiveMQConnectionFactory conFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
final QueueConnection connection = conFactory.createQueueConnection();
final Session session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
final Destination destination = new ActiveMQQueue("MJ_SAF");
final MessageProducer producer = session.createProducer(destination);
Message message = session.createTextMessage("test");
producer.send(message);
}
by above code all things is nice:
I don't understand this behavior. Does anyone know reasons of this?
You have the property ScheduledMessage.AMQ_SCHEDULED_REPEAT set to 1, so it will repeat 1 time giving you a total of 2 messages.
See here for the descriptions of the properties. As I understand it, your current set up will wait 20 milliseconds, publish 1 message, wait 1 millisecond, and publish a second message, then end.

Jboss Messaging JMS

I successfully managed to send the message to queue name ReceiverQueue on my localhost Jboss server, how can I retrieve message I sent to it or how do I check if there is any messages in the queue if any retrieve them. or can I get an explanation of some sort what is the best way to do this. Thank you
A working send/receive tutorial would be accept as well. Anything that will get me to just send to the queue and receive message from that queue will get accepted answer.
I'm using Spring.
I want a solution that does it using application context with bean injection ..
Standard JMS API steps:
1. Create a javax.naming.Context with the access details of the server
context = new InitialContext(environment)
2. Look up javax.jms.QueueConnectionFactory in the context. Factory name is specific to the JMS server
factory = (QueueConnectionFactory)context.lookup(factoryName)
3. Create a javax.jms.QueueConnection
connection = factory.createQueueConnection(...)
4. Create a javax.jms.QueueSession
session = connection.createQueueSession(...)
5. Look up your javax.jms.Queue in the context
queue = (Queue) context.lookup(qJndiName)
Till now it is the same as sending....
6. Create a javax.jms.QueueReceiver with the session
receiver = session.createReceiver(queue)
7. JMS API provides 2 ways to retrieve a message:
7.a Wait for a message with one of the receiver.receive() methods
7.b Implement javax.jms.MessageListener in your class and register it as the listener
receiver.setMessageListener(this)
JMS API will call your onMessage() method whenever a new message arrives
8. Don't forget to start the listener:
connection.start()
9. Close the context (very important, when you access multiple JMS servers from the same program):
context.close()
The above is a typical solution from a stand-alone application. In EJB environment you should use message driven beans. You can find ino on them on http://java.sun.com/javaee/6/docs/tutorial/doc/gipko.html and a tutorial on http://schuchert.wikispaces.com/EJB3+Tutorial+5+-+Message+Driven+Beans
Here is the working example you've asked for:
import java.util.Hashtable;
import javax.naming.*;
import javax.jms.*;
public class JMSJNDISample implements MessageListener {
public static final String JNDI_URL = "jnp://localhost:1099";
public static final String JNDI_CONTEXT_FACTORY = "org.jnp.interfaces.NamingContextFactory";
public static final String JMS_USER = null;
public static final String JMS_PASSWORD = null;
public static final String JMS_CONNECTION_FACTORY = "MyConnectionFactory";
public static final String QUEUE_JNDI_NAME = "ReceiverQueue";
QueueConnection qConn = null;
QueueSession qSession = null;
QueueSender qSender = null;
QueueReceiver qReceiver = null;
public JMSJNDISample () {
}
public void init() throws JMSException, NamingException {
// Set up JNDI Context
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_CONTEXT_FACTORY);
env.put(Context.PROVIDER_URL, JNDI_URL);
if (JMS_USER != null)
env.put(Context.SECURITY_PRINCIPAL, JMS_USER);
if (JMS_PASSWORD != null)
env.put(Context.SECURITY_CREDENTIALS, JMS_PASSWORD);
Context jndiContext = new InitialContext(env);
// Lookup queue connection factory
QueueConnectionFactory cFactory = (QueueConnectionFactory)jndiContext.lookup(JMS_CONNECTION_FACTORY);
// Create Connection
if (JMS_USER == null || JMS_PASSWORD == null)
qConn = cFactory.createQueueConnection();
else {
qConn = cFactory.createQueueConnection(JMS_USER, JMS_PASSWORD);
}
// Create Session
qSession = qConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
// Lookup Queue
Queue queue = (Queue) jndiContext.lookup(QUEUE_JNDI_NAME);
// Create Queue Sender
qSender = qSession.createSender(queue);
// Create Queue Receiver
qReceiver = qSession.createReceiver(queue);
qReceiver.setMessageListener(this);
// Start receiving messages
qConn.start();
// Close JNDI context
jndiContext.close();
}
public void sendMessage (String str) throws JMSException {
TextMessage msg = qSession.createTextMessage(str);
qSender.send(msg);
}
public void onMessage (Message message) {
try {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage)message;
System.out.println("Text Message Received: "+textMessage.getText());
} else {
System.out.println(message.getJMSType()+" Message Received");
}
} catch (JMSException je) {
je.printStackTrace();
}
}
public void destroy() throws JMSException {
if (qSender != null) qSender.close();
if (qReceiver != null) qReceiver.close();
if (qSession != null) qSession.close();
if (qConn != null) qConn.close();
}
public static void main(String args[]) {
try {
JMSJNDISample sample = new JMSJNDISample();
// Initialize connetion
sample.init();
// Send Message
sample.sendMessage("Hello World");
// Wait 2 sec for answer
Thread.sleep(2000);
// Disconnect
sample.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Other than having a MessageDrivenBean listening to that queue?
EDIT:
You are using spring just to create the payload, right? JMS is a JavaEE spec. You don't need to use Spring for actually sending/receiving messages. You don't have to manually check whether there are messages in the queue etc., either. All you need to do is have an MDB(MessageDrivenBean) set up like this,
#MessageDriven(activationConfig = {
#ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(
propertyName = "destination", propertyValue = "queue/myqueue")
})
public class MyMessageDrivenBean implements MessageListener {
public void onMessage(Message message) {
ObjectMessage objMsg = (ObjectMessage) message;
Payload payload = (Payload)objMsg.getObject();
//do stuff
}
}
And then send some JMS messages.
#Stateless
public class QueuerBean implements QueuerLocal {
#Resource(mappedName = "java:/JmsXA")
private ConnectionFactory jmsConnectionFactory;
#Resource(mappedName = "queue/myqueue")
private Queue queue;
private void queue(MyPayload payload) {
try {
Connection connect = jmsConnectionFactory.createConnection();
Session session = connect.createSession(false,
Session.DUPS_OK_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);
// create a JMS message and send it
ObjectMessage objMsg = session.createObjectMessage(payload);
producer.send(objMsg);
producer.close();
session.close();
connect.close();
} catch (JMSException e) {
log.error("Bad thing happened", e);
}
}
}
The queue is configured by the annotation. When a message is sent, JBoss will automatically trigger the MDB.
Here's an example showing how to set up a message-driven POJO in Spring. I'd recommend following this idiom if you're already using Spring.
As for the part about seeing how many messages are on the queue, I'd say you should be using the admin console for JBOSS, not your code.
I would recommend also using a tool like HermesJMS (http://www.hermesjms.com/confluence/display/HJMS/Home) to inspect the queue manager and queues. It's a great debugging tool.

Categories

Resources