7

GeronimoのJNDIQueueConnectionFactoryを介してを検索しようとしています。Queueは正常に返されますQueueが、QueueConnectionFactoryルックアップは常にnullを返します。はスローされませんNamingException。これは、JNDI名が正しくない場合に予想されることです。

誰かが私が間違っていることを見ることができますか?以下のテストコードは次のように出力します。

true
false

import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JndiTest
{
    private final static String QUEUE_NAME = "jca:/org.apache.geronimo.configs/activemq-ra/JCAAdminObject/SendReceiveQueue";
    private final static String FACTORY_NAME = "jca:/org.apache.geronimo.configs/activemq-ra/JCAManagedConnectionFactory/DefaultActiveMQConnectionFactory";

    public static void main(String[] args) throws NamingException
    {
        InitialContext ctx = new InitialContext();
        QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup(FACTORY_NAME);
        Queue queue = (Queue)ctx.lookup(QUEUE_NAME);
        System.out.println(factory == null);
        System.out.println(queue == null);      
    }

}

違いが生じる場合:クラスパスにopenejb-client-3.0.1.jar、geronimo-ejb_3.0_spec-1.0.1.jar、activemq-core-4.1.2-G20090207.jarを追加しました。私のjndi.propertiesファイルには次のプロパティがあります。

java.naming.factory.initial = org.apache.openejb.client.RemoteInitialContextFactory
java.naming.provider.url = ejbd://127.0.0.1:4201
4

4 に答える 4

14

例外をスローしない理由は、リソースにアクセスしたときに発生するClassLoadExceptionがあるためです。

そして、それが起こっている理由は、クラス:com.sun.jndi.url.jca.jcaURLContextFactoryがResourceManagerから呼び出されたClassLoaderによって検索されているためです。

Factory名を他の名前に変更すると、NamingExceptionが表示されますが、ルックアップの場合、ClassNotFound/IllegalStateなどの例外の場合は例外は発生しません。

したがって、ActiveMQの依存関係を分析する必要があります。Update1:​​考えられる理由の1つは、ファクトリオブジェクトは管理対象環境でのみインスタンス化できることです。コードをアプリケーションクライアントとして実行していますか?

Update2:この動作の原因として見つかった他のいくつかのポインター:

openejb jndi実装は、ejbsのみを公開し、他のリソースは公開しません。j2eeアプリクライアントがあり、jmsを使用する場合は、activemqアダプターのコピーをクライアントにデプロイする必要があります。次に、j2ee java:comp/envコンテキストを使用して自分のものを見つけることができます。

ActiveMQサイトでこれを見つけました:

ActiveMQのJNDI実装は、ネーミングサーバーと通信しません。これは、JMSインスタンスから直接トピックとキューを取得できるようにするJNDIクライアントの簡略版です。したがって、ネーミングサーバーアドレスを指定する代わりに、JMSサーバーアドレスを指定する必要があります。ほとんどのJNDI実装では、java.naming.provider.urlプロパティを使用してネーミングサーバーのアドレスを指定します。ActiveMQはbrokerURLを使用します。代わりにjava.naming.provider.urlを使用すると、ActiveMQがブローカー全体をロードしようとします。

JNDIを使用して接続する方法の詳細を参照してください。

説明で使用される初期コンテキストファクトリは次のとおりです。org.apache.activemq.jndi.ActiveMQInitialContextFactory

JNDIでテストするためのいくつかのサンプルコードはここにあります

単純なJavaクライアントを作成しました。プロバイダーのURLの下に、使用されているbrokerURLがあります。

    Properties props = new Properties();            
props.put(Context.INITIAL_CONTEXT_FACTORY,
             "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
    //props.put(Context.PROVIDER_URL,"vm://localhost");//Either this or below
    props.put(Context.PROVIDER_URL,"tcp://localhost:65432"); 
    props.put("queue.SendReceiveQueue",
         "org.apache.geronimo.configs/activemq-ra/JCAAdminObject/SendReceiveQueue");
      
    InitialContext context = new InitialContext(props);   
    QueueConnectionFactory connectionFactory = (QueueConnectionFactory)context.lookup
                                                               ("ConnectionFactory");
    Queue q = (Queue) context.lookup("SendReceiveQueue");
    System.out.println("conn is : "  + connectionFactory.getClass().getName());
    System.out.println("queue is : " + q.getQueueName());

このプログラムは出力を提供します:

connは:org.apache.activemq.ActiveMQConnectionFactoryキューは:org.apache.geronimo.configs / activemq-ra / JCAAdminObject / SendReceiveQueue

于 2009-08-29T23:20:51.397 に答える
1

私はTomcat/Geronimo J2EE jar / Geronimo JMS Jar / ActiveMQ 4と同等の構成を持っていますが、jndi.propertieファイルについて少し混乱しています。私のはこのように見えます:

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory

java.naming.provider.url = tcp://localhost:61616

connectionFactoryNames = connectionFactory , TopicConnectionFactory

大きな違いは、最初のコンテキストがリモートであることは明らかです。そのほかに、connectionFactoryNamesを指定する必要があります。そうしないと、NamingExceptionが発生します。

于 2009-09-02T12:15:26.237 に答える
1

理由はわかりませんが、私にとっては、コンテキストを使用してもうまくいきませんでした。メッセージは送信されているようですが、私のコンシューマの onMessage が呼び出されていません。

コンテキストを使用しても例外はスローされませんが、機能しません:

import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;

public class HelloClient {

public static void main(String[] args) throws Exception {
    Properties ppt2 = new Properties();
    ppt2.put(Context.INITIAL_CONTEXT_FACTORY,
            "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
    ppt2.put(Context.PROVIDER_URL, "tcp://localhost:61616");
    ppt2.put("topic.MessageDestinationTopic", "console.jms/TopicQueue/JCAAdminObject/MessageDestinationTopic");
    Context ctx2 = new InitialContext(ppt2);

    TopicConnectionFactory factory = (TopicConnectionFactory) ctx2.lookup("ConnectionFactory");
    TopicConnection connection = factory.createTopicConnection();
    TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    Topic topic = (Topic) ctx2.lookup("MessageDestinationTopic");

    MessageProducer producer = session.createProducer(topic);

    TextMessage msg = session.createTextMessage();
    msg.setText("this is a test message");
    producer.send(msg);
    producer.close();
    session.close();
    System.out.println("Message published. Please check application server's console to see the response from MDB");
    ctx2.close();
    System.exit(0);

}

}

以下のコード (コンテキストなし) を使用するとうまくいきます。

import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;

public class HelloClient {

    public static void main(String[] args) throws Exception {

        TopicConnectionFactory factory = new org.apache.activemq.ActiveMQConnectionFactory("tcp://localhost:61616");
        TopicConnection connection = factory.createTopicConnection();
        TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic("MessageDestinationTopic");

        MessageProducer producer = session.createProducer(topic);

        TextMessage msg = session.createTextMessage();
        msg.setText("this is a test message");
        producer.send(msg);
        producer.close();
        session.close();
        System.out.println("Message published. Please check application server's console to see the response from MDB");
        System.exit(0);

    }

}
于 2011-04-29T16:18:58.723 に答える
0

ここには 2 つの参加者がいて、JNDI で何かを探しています。他の誰かがそこに置かなければなりませんでした。あなたの環境の詳細はわかりませんが、そのような問題に対する私のアプローチは

  • 名前空間を調べてください - そこには何がありますか? JNDI 参照ツールはありますか?
  • JNDI に登録されているはずのサービスのログを注意深く調べてください。エラーは報告されていますか?
于 2009-08-26T09:23:18.223 に答える