MessageListener не прослушивает сообщения в очереди Oracle - PullRequest
1 голос
/ 08 января 2012

Я внедрил Oracle Advanced Queue и пишу программу для слушателя.Ниже приведен мой пример:

package com.myprog;

import java.io.File;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.jms.TextMessage;

import oracle.jms.AQjmsFactory;
import oracle.jms.AQjmsSession;

import org.apache.log4j.Logger;

public class abc implements MessageListener, ExceptionListener {
private static String queueUserName = "admin";
private static String queueName = "my_queue";

// Initialize the logger
private static Logger log = Logger.getLogger(abc.class);

public static void main(String[] args) {
    final String METHOD_NAME  = "main()";

    abc a = new abc();              

      Queue queue;
      try {
       QueueConnection QCon = getConnection();  
       Session session = QCon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
       QCon.start();

       queue = ((AQjmsSession) session).getQueue(queueUserName, queueName);
       MessageConsumer consumer = session.createConsumer(queue);       

       consumer.setMessageListener(a);
       QCon.setExceptionListener(a);

       consumer.close();
       session.close();
       QCon.close();
      } catch (JMSException e) {  
       e.printStackTrace();
      }         

}

public static QueueConnection getConnection() {
  String hostname = "myhost";
  String oracle_sid = "mysid";
  int portno = 1521;
  String userName = "myapp";
  String password = "pwd";
  String driver = "thin";
  QueueConnectionFactory QFac = null;
  QueueConnection QCon = null;
  try {
   // get connection factory , not going through JNDI here
   QFac = AQjmsFactory.getQueueConnectionFactory(hostname, oracle_sid, portno,driver);

   // create connection
   QCon = QFac.createQueueConnection(userName, password);
   } catch (Exception e) {
    e.printStackTrace();
  }
  return QCon;
}

@Override
public void onException(JMSException e) {
    log.error(e);       
}

@Override
public void onMessage(Message message) {
     TextMessage msg = (TextMessage) message;

     try {
         String m = msg.getText();
         System.out.println("m="+m);
         log.info("MESSAGE RECEIVED " + m);
     } catch (JMSException e) {
        log.error(e); 
     }
}

}

Обратите внимание, что эта программа является автономной программой, которая будет продолжать работать и прослушивать сообщения в очереди оракула.

К сожалению, когда я создаю флягу этого файла класса и запускаю его, он просто запускается, а затем выходит и потребляет только 1 сообщение в очереди.Почему слушатель не продолжает бегать и слушать очередь?

Я думал, что он будет продолжать прослушивать и извлекать все сообщения в очереди, а затем навсегда останется в режиме прослушивания, но это не так.

Спасибо, если кто-нибудь скажет мне, что происходит.

Спасибо

Ответы [ 2 ]

2 голосов
/ 08 января 2012

Это все потому, что вы закрываете соединение / сеанс сразу после запуска. Вам нужен процесс для запуска потока демона, который всегда работает в JVM. JMS не несет ответственности за поддержание работы JVM. Для этого вам нужно создать тему, которая только что спала.

0 голосов
/ 08 января 2012

Вот пример того, как другой пример JMS зацикливается для обработки нескольких сообщений.

Performs a JNDI lookup of the ConnectionFactory and Destination.
Creates a Connection and a Session.
Creates a MessageConsumer:

consumer = session.createConsumer(dest);
Starts the connection, causing message delivery to begin:

connection.start();
Receives the messages sent to the destination until the end-of-message-stream control message is received:

while (true) {
  Message m = consumer.receive(1);
  if (m != null) {
    if (m instanceof TextMessage) {
      message = (TextMessage) m;
      System.out.println("Reading message: " +
        message.getText());
    } else {
      break;
    }
  }
}

Because the control message is not a TextMessage, the receiving program terminates the while loop and stops receiving messages after the control message arrives.
Closes the connection in a finally block, automatically closing the session and MessageConsumer.

Возможно, вам удастся просто обернуть этот код в цикл while.Это зависит от того, как JMS заставляет вас обрабатывать объекты подключения и сеанса, а также от того, закрываются ли они автоматически, но вы можете попытаться обернуть только это.

while(true) {
       QCon.start();

       queue = ((AQjmsSession) session).getQueue(queueUserName, queueName);
       MessageConsumer consumer = session.createConsumer(queue);       

       consumer.setMessageListener(a);
       QCon.setExceptionListener(a);

       consumer.close();
}
...