Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么QueueConnectionFactory的JNDI查找返回null?_Java_Jakarta Ee_Jms_Jndi_Geronimo - Fatal编程技术网

Java 为什么QueueConnectionFactory的JNDI查找返回null?

Java 为什么QueueConnectionFactory的JNDI查找返回null?,java,jakarta-ee,jms,jndi,geronimo,Java,Jakarta Ee,Jms,Jndi,Geronimo,我试图通过Geronimo的JNDI查找QueueConnectionFactory和Queue。队列返回良好,但队列连接工厂查找始终返回null。它不会抛出NamingException,这是我在JNDI名称不正确时所期望的 有人能看出我做错了什么吗?以下测试代码输出: true false 如果有区别:我已经将openejb-client-3.0.1.jar、geronimo-ejb_3.0_spec-1.0.1.jar和activemq-core-4.1.2-G20090207.jar添加

我试图通过Geronimo的JNDI查找
QueueConnectionFactory
Queue
队列
返回良好,但
队列连接工厂
查找始终返回null。它不会抛出
NamingException
,这是我在JNDI名称不正确时所期望的

有人能看出我做错了什么吗?以下测试代码输出:

true false 如果有区别:我已经将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 java.naming.factory.initial=org.apache.openejb.client.RemoteInitialContextFactory java.naming.provider.url=ejbd://127.0.0.1:4201
这里有两个参与者,您正在JNDI中寻找一些东西。必须有人把它放在那里。我不知道你们环境的具体情况,但我解决这些问题的方法是

  • 探索名称空间-有什么?你有JNDI浏览工具吗
  • 在日志中查找应该向JNDI注册的服务,它是否报告任何错误

它不引发异常的原因是-访问资源时会出现ClassLoadException

发生这种情况的原因是,ResourceManager调用的类加载器正在搜索类:com.sun.jndi.url.jca.jcaURLContextFactory

如果您将工厂名称更改为其他名称,那么您将看到NamingException,但在查找的情况下,对于ClassNotFound/IllegalState等异常,不会引发异常

因此,需要分析ActiveMQ的依赖关系。 Update1:可能的原因之一是工厂对象只能在托管环境中实例化。您是否将代码作为应用程序客户端运行

Update2:找到了导致此行为的其他一些指针:

仅openejb jndi实现 公开EJB,而不是任何其他资源。 如果您有j2ee应用程序客户端,并且 如果希望使用jms,则需要 部署activemq适配器的副本 在客户机上。然后您可以使用 j2ee java:要查找的comp/env上下文 你的东西。

在ActiveMQ站点上找到此项:

ActiveMQ的JNDI实现不与命名服务器通信。它是 JNDI客户端的精简版本,只允许获取主题和 直接从JMS实例排队。因此,您必须提供JMS服务器地址,而不是提供命名服务器地址。大多数JNDI实现使用java.naming.provider.url属性指定命名服务器的地址。ActiveMQ使用brokerURL。使用java.naming.provider.url将导致ActiveMQ尝试加载整个代理

有关如何:

解释中使用的初始上下文工厂是: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/activemqra/JCAAdminObject/SendReceiveQueue

我有一个相当于Tomcat/geronimo J2EE jar/geronimo JMS jar/activemq 4的配置 我对你的jndi.property文件有点困惑。 我的看起来像这样:

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

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

connectionFactoryNames=connectionFactory,TopicConnectionFactory


很明显,最大的区别在于您的初始上下文是远程的。除此之外,我必须提供connectionFactoryNames,否则我会得到一个NamingException

我不知道为什么,但对我来说,使用上下文是行不通的。消息似乎已发送,但未调用我的消费者的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);

    }

}

Geronimo提供了一个JNDI浏览工具,两个JNDI名称似乎都存在。在我的测试工具中更改名称会产生一个NamingException,所以它一定是在查找某个东西。对,但它在查找什么?是谁把它放在那里的?对我来说,所有这些都指向了JMS提供程序中的问题,而不是您的代码中的问题。谢谢你周到、透彻的回答。
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);

    }

}