[英]Apache Camel JMS: “Not allowed to create destination” when trying to connect to a queue
我正在尝试在骆驼中设置一个从JMS队列读取消息的路由。
该应用程序使用Tibco,我不允许在此处发布任何数据,但是工厂和队列的路径遵循/ path / to / queueName:type的格式,其中type可以是qcf(队列连接工厂)和queue 。
我正在使用Spring-DSL,XML是:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">...</prop>
<prop key="java.naming.provider.url">...LDAP Server URL...</prop>
<prop key="java.naming.referral">follow</prop>
<prop key="java.naming.security.credentials">...</prop>
<prop key="java.naming.security.principal">uid=...,ou=...,dc=...,dc=...</prop>
</props>
</property>
</bean>
<bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="/path/to/queueConnectionFactory:qcf"/>
</bean>
<bean id="authenticatedConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="jmsQueueConnectionFactory"/>
<property name="username" value="..."/>
<property name="password" value="..."/>
</bean>
<bean id="testjms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="authenticatedConnectionFactory"/>
</bean>
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<route id="jmsRouteTest">
<from uri="testjms:queue:/path/to/queue:queue" />
<to uri="file:c:\inbox?fileName=jmsMessage.txt" />
</route>
</camelContext>
当应用程序运行时,它会在日志中不断抛出以下行:
12:41:19:385 - WARN - DefaultMessageListenerContainer - Setup of JMS message listener invoker failed for destination 'path/to/queue:queue' - trying to recover. Cause: Not allowed to create destination
12:41:20:494 - INFO - DefaultMessageListenerContainer - Successfully refreshed JMS Connection
要注意的一件事是目标的第一个斜杠“ /”消失了,但是如果我从URI中删除“ queue:”,则会发生相同的错误,但是目标变为“ / path / to / queue:queue”。
我已经搜索了该错误,并在stackoverflow上找到了一个问题: 有谁确切知道javax.jms.InvalidDestinationException是什么:不允许创建目标方法?
为了确保配置正确,我创建了以下类(将完全相同的设置从Spring XML复制到该类):
import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.put("java.naming.provider.url", "...LDAP Server URL...");
properties.put("java.naming.factory.initial", "...");
properties.put("java.naming.referral", "follow");
properties.put("java.naming.security.principal", "uid=...,ou=...,dc=...,dc=...");
properties.put("java.naming.security.credentials", "...");
properties.put("JmsConnectionFactory", "/path/to/queueConnectionFactory:qcf");
properties.put("JmsDestinationName", "/path/to/queue:queue");
properties.put("JmsUserName", "...");
properties.put("JmsPassword", "...");
Context context = null;
QueueConnection connection = null;
QueueSession session = null;
QueueReceiver receiver = null;
context = new InitialContext(properties);
Queue queue = (Queue) context.lookup((String) properties.get("JmsDestinationName"));
QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) context.lookup((String) properties.get("JmsConnectionFactory"));
connection = queueConnectionFactory.createQueueConnection((String) properties.getProperty("JmsUserName"),
properties.getProperty("JmsPassword"));
session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
receiver = session.createReceiver(queue);
while (true) {
TextMessage message = (TextMessage) receiver.receive();
System.out.println("Received: " + message.getText());
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
String s = bufferRead.readLine();
if ("b".equals(s)) {
break;
}
}
connection.close();
}
}
通过此类,我可以读取队列中的消息。
有人遇到过这个问题吗?
如果您需要更多信息,请告诉我。
谢谢。
听起来您需要先让一些Tibco管理员来在Tibco消息代理上创建该队列。
谢谢您的帮助,但是解决方案非常简单。
我已经下载了要调试的源代码,并在名为DefaultMessageListenerContainer的Spring类中结束了该类,在会话中调用createConsumer方法时引发了异常。
这使我想到了Spring论坛中的一个主题http://forum.spring.io/forum/spring-projects/integration/jms/129634-dbus-jms-message-listener-javax-jms-jmssecurityexception-not-permitted
基本上,它说为了防止发生此错误,应该使用JNDI而不是session.createQueue()来获取目标。
然后,我搜索了在端点URI中使用JNDI名称的方法,并找到了http://camel.465427.n5.nabble.com/JMS-queue-JNDI-instead-of-physical-name-td494620.html
基本上,这表明需要目标解析器。 添加它可以解决该错误。
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop...</prop>
</props>
</property>
</bean>
<bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="..."/>
</bean>
<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="cache" value="true" />
</bean>
<bean id="testjms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
<property name="destinationResolver" ref="jmsDestinationResolver" />
</bean>
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<route id="testRoute">
<from uri="testjms:jmsJNDIName?connectionFactory=jmsQueueConnectionFactory&username=...&password=..." />
<to uri="file:C:\inbox" />
</route>
</camelContext>
tl; dr-使用JNDI获取队列并指定目标解析器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.