2012-01-08 4 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); 
    } 
} 

}

このプログラムは、Oracleキュー内のメッセージを聞い&を実行し続けるスタンドアロンのプログラムであることに注意してください。以下は、私のサンプルです。私は、このクラスファイルのJAR &実行、それを作成したときに

は残念ながら、それだけで&を終了し、その後&を実行し、キュー内の1つのだけのメッセージを消費します。リスナーがキューを聞いて&を実行し続けるのはなぜですか?

私はそれが待ち続けると思った&キュー内のすべてのメッセージを取得する&その後、リッスンモードは永遠に残りますが、そのようには動作しません。

何か問題があると私には分かりますか?

おかげ

+0

tryブロックの先頭からwhile(真)でブロックの最後まですべてのコードをラップして、メッセージを消費するとそのキューの設定をすべて再実行し、別のメッセージを待っているようにしてください。私はそれがメインであるので、あなたが各メッセージを処理した後にそのセッションを作成しなければならないかもしれないと思います。これは恒久的な解決策ではないかもしれませんが、今のところそれが得られるかもしれません。 – Logan

+0

@Logan、ブロックしようとしていますか?それは主な方法のものですか? – Mike

+0

はい、申し訳ありません。メインメソッドの1つ。 – 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

私はそれをキューのキューの前と、メインメソッドのキャッチブロックの後に置いています。基本的にはすべてのコードをラップします。最初に複数回実行されているかどうかを確認するだけで、そのコードのどれかを取り出して一度だけ実行できるかどうかを判断できます。 – Logan

+0

ループ中に置くとCPUにかかるのですか?待ち行列にメッセージがないときはどうなりますか?それはCPUを取るだろうか? – Mike

2

起動時にすぐに接続/セッションを終了していることが原因です。 JVMで永久に実行されるデーモンスレッドを開始するプロセスが必要です。 JMSは、JVMの実行を維持する責任を負いません。あなたはそれを達成するためにただ眠っているスレッドを作成する必要があります。

+0

サンプルコードを提供できますか? – Mike

+0

スレッドが作成されたら、いつスリープする必要がありますか?上記のコードの例を挙げてください。 – Mike

関連する問題