我正在尝试通过 Geronimo 的 JNDI 查找 QueueConnectionFactory
和 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 添加到我的类(class)路径,我的 jndi.properties 文件具有以下属性:
java.naming.factory.initial = org.apache.openejb.client.RemoteInitialContextFactory java.naming.provider.url = ejbd://127.0.0.1:4201
最佳答案
它没有抛出异常的原因是——访问资源时出现了ClassLoadException。
发生这种情况的原因是类:com.sun.jndi.url.jca.jcaURLContextFactory 正在被 ResourceManager 调用的 ClassLoader 搜索。
如果您将工厂名称更改为其他名称,那么您将看到 NamingException - 但在 lookup 的情况下,对于 ClassNotFound/IllegalState 等异常 - 不会引发异常。
因此需要分析ActiveMQ的依赖关系。 Update1:可能的原因之一是工厂对象只能在托管环境中实例化。您是否将代码作为应用程序客户端运行?
更新 2:针对此行为的原因找到了一些其他指针:
the openejb jndi implementation only exposes ejbs, not any other resources. If you have a j2ee app client, and you wish to use jms, you need to deploy a copy of the activemq adapter on the client. You can then use the j2ee java:comp/env context to find your stuff.
在 ActiveMQ 网站上找到:
ActiveMQ's JNDI Implementation does NOT talk to the naming server. It's a stripped down version of a JNDI client that just allows to get Topics and Queues directly from a JMS instance. So, instead of supplying the naming server address, you have to supply the JMS server address.Most JNDI implementations use the java.naming.provider.url property to specify the naming server's address. ActiveMQ uses the brokerURL one. Using the java.naming.provider.url one instead will result in ActiveMQ trying to load the whole Broker.
查看有关如何 Connect using JNDI 的更多信息:
解释中使用的初始上下文工厂是:org.apache.activemq.jndi.ActiveMQInitialContextFactory
可以找到一些使用 JNDI 进行测试的示例代码 here
我写了一个简单的 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
关于java - 为什么我对 QueueConnectionFactory 的 JNDI 查找返回空值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1333221/