2012-01-08 1 views
1

Oracle Advanced Queue가 구현되었습니다. & 청취자 프로그램을 작성하고 있습니다.MessageListener가 Oracle 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 메시지를 소비 종료합니다. 청취자가 대기열 수신 대기 중 &을 계속 실행하지 않는 이유는 무엇입니까?

나는 계속 듣고 있다고 생각했다. & 대기열에있는 모든 메시지를 검색한다. & 그런 다음 영원히 듣기 모드로 남아있을 것이지만, 그런 식으로 행동하지는 않는다.

무엇이 잘못되었는지 알 수있는 사람이 있으면 감사하게 생각하십시오.

감사

+0

try 블록의 시작 부분에서 while (true)을 사용하여 블록의 끝까지 래핑 해보십시오. 그러면 메시지를 소비 한 후 해당 큐 설정을 다시 실행하고 다른 메시지를 기다리고 있습니다. . 나는 그것이 메인에 있기 때문에 각 메시지를 처리 ​​한 후에 그 세션을 만들어야 할 수도 있다고 생각한다. 이것은 영구적 인 해결책은 아닐지 모르지만 지금 당장 얻을 수 있습니다. – Logan

+0

@Logan, 블록을 사용하는 것은 무엇입니까? 주요 방법에서 나온 것입니까? – Mike

+0

예, 죄송합니다. 주요 방법에있는 것. – Logan

답변

0

는 여기에 또 다른 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(); 
} 
+0

내 코드에서 while 루프를 어디에 넣을 수 있는지 말해 줄 수 있습니까? – Mike

+0

대기열 큐 앞에 넣고 기본 메서드에서 catch 블록을 넣은 다음 기본적으로 모든 코드를 래핑합니다. 처음에 두 번 이상 실행되는지 확인하기 만하면 그 코드 중 하나라도 빠져 나와 한 번만 실행될 수 있는지 확인할 수 있습니다. – Logan

+0

루프를 넣으면 CPU가 걸릴까요 ??? 대기열에 메시지가 없을 때 어떤 일이 발생합니까? CPU가 필요합니까? – Mike

2

시작 후 바로 연결/세션을 종료하기 때문에 모든 것이 있습니다. JVM에서 영원히 실행되는 데몬 스레드를 시작하는 프로세스가 필요합니다. JMS는 JVM 실행을 유지할 책임이 없습니다. 이를 달성하기 위해 잠 들어있는 스레드를 만들어야합니다.

+0

샘플 코드를 제공 할 수 있습니까? – Mike

+0

스레드가 만들어지면 언제 잠자기 모드로 전환해야합니까? 위 코드에 대한 예제를 제공해 주시겠습니까? – Mike