【发布时间】:2017-01-03 18:48:57
【问题描述】:
我有 WildFly 10.1.0.Final,这里有 Artemis 1.1.0 配置 jndi.properties 的正确方法是什么?:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=http-remoting://127.0.0.1:8080
jboss.naming.client.ejb.context=false
此 worket 与 WildFly 9.0.0.Final 有 HornetQ:
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=http-remoting://127.0.0.1:8080
jboss.naming.client.ejb.context=false
我使用的是 Spring 4.3.2,Spring-jms,并在 Maven POM.xml 中包含了 wildfly-jms-client-bom。 接下来是我的连接工厂。对于 Wildfly 9,我尝试 InitialContext.doLookup(..) 和这项工作。但在 WildFly 10 中,情况就不同了。
我的主要配置文件是:
@Configuration
@ComponentScan(basePackages = "org")
@Import({
MessagingConfiguration.class,
MessagingListenerConfiguration.class
})
public class AppConfig {
//Put Other Application configuration here.
}
.
package org.jms.configuration;
@Configuration
public class MessagingConfiguration {
@Bean
public ConnectionFactory connectionFactory() throws NamingException{
ConnectionFactory connectionFactory = InitialContext.doLookup("java:/ConnectionFactory");
return connectionFactory;
}
/*
@Bean
public JmsTemplate jmsTemplate() throws NamingException {
JmsTemplate template = new JmsTemplate();
template.setConnectionFactory(connectionFactory());
//template.setDefaultDestinationName(ORDER_RESPONSE_QUEUE);
return template;
}
*/
}
我还有下一个:
package org.jms.configuration;
@Configuration
@EnableJms
public class MessagingListenerConfiguration {
@Autowired
ConnectionFactory connectionFactory;
public MessagingListenerConfiguration() {
System.out.println("MessagingListenerConfiguration::Constructor!!");
}
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setConcurrency("1-1");
return factory;
}
}
终于有了这个监听器。
package org.jms.messaging;
import javax.jms.JMSException;
import org.gasmart.jms.model.Product;
import org.gasmart.jms.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Component;
@Component
public class MessageReceiver {
//private static final String ORDER_QUEUE = "order-queue";
/*
* <jms-queue name="shatTopic" entries="java:/jms/queue/shat java:/jboss/exported/jms/queue/shat"/>
*/
private static final String ORDER_QUEUE = "shat";
public MessageReceiver() {
System.out.println(">>>>>>>>>>>>>>>>>>> OK");
}
@Autowired
OrderService orderService;
@JmsListener(destination = ORDER_QUEUE)
public void receiveMessage(final Message<String> message) {
MessageHeaders headers = message.getHeaders();
System.out.println("MessageReceiver::receiveMessage(product) Application : headers received : "+headers);
//orderService.processOrder(product);
}
}
我收到此错误:
20:04:42,971 WARN [org.springframework.jms.listener.DefaultMessageListenerContainer] (DefaultMessageListenerContainer-124) 目标“shat”的 JMS 消息侦听器调用程序设置失败 - 试图恢复。 原因:没有名字为shat的队列
20:04:42,971 INFO [org.springframework.jms.listener.DefaultMessageListenerContainer] (DefaultMessageListenerContainer-124) 成功刷新 JMS 连接
MessageReceiver 类中声明的 shat 队列。 我的standalone-full.xml 是下一个:
<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
<server name="default">
<security-setting name="#">
<role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
</security-setting>
<security-setting name="jms.topic.chat">
<role name="guest2" send="true" consume="true" create-non-durable-queue="true"/>
</security-setting>
<address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
<http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
<http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
<param name="batch-delay" value="50"/>
</http-connector>
<in-vm-connector name="in-vm" server-id="0"/>
<http-acceptor name="http-acceptor" http-listener="default"/>
<http-acceptor name="http-acceptor-throughput" http-listener="default">
<param name="batch-delay" value="50"/>
<param name="direct-deliver" value="false"/>
</http-acceptor>
<remote-acceptor name="websocket-stomp" socket-binding="netty-ws"/>
<in-vm-acceptor name="in-vm" server-id="0"/>
<jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
<jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
<jms-queue name="shatTopic" entries="java:/jms/queue/shat java:/jboss/exported/jms/queue/shat"/>
<connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>
<connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>
<pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
</server>
</subsystem>
我已经定义了队列,这是正确定义的:
关于如何声明队列的参考资料可以参考这里:http://www.mastertheboss.com/jboss-server/jboss-jms/jboss-jms-configuration
为什么连接不上??我不明白。其实我试过很多很多方法,都不行。
更新:2016 年 8 月 29 日 - 上午 10:00
我发现,如果我在加载应用程序后重新启动所有实际部署的应用程序的 wildfly,如果我连接一个客户端(我有一个使用 Websocket 将消息直接生成到“jms.queue.shat”队列的 Web 客户端通过带有 stomp.js 的 STOMP)并发送消息,应用程序(java)正确地使用消息。但是,如果我在应用程序正常工作后重新部署它,这会产生错误。 错误是下一个:
10:43:51,607 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool - 113) WFLYUT0021: Registered web context: /ServerApp
10:43:51,632 INFO [org.jboss.as.server] (DeploymentScanner-threads - 2) WFLYSRV0010: Deployed "ServApp.war" (runtime-name : "ServApp.war")
10:43:56,588 INFO [org.springframework.jms.listener.DefaultMessageListenerContainer] (DefaultMessageListenerContainer-2) JMS message listener invoker needs to establish shared Connection
10:43:56,592 ERROR [org.springframework.jms.listener.DefaultMessageListenerContainer] (DefaultMessageListenerContainer-2) Could not refresh JMS Connection for destination 'shat' - retrying using FixedBackOff{interval=5000, currentAttempts=0, maxAttempts=unlimited}. Cause: Failed to create session factory; nested exception is java.lang.IllegalStateException: Server locator is closed (maybe it was garbage collected)
10:44:01,592 ERROR [org.springframework.jms.listener.DefaultMessageListenerContainer] (DefaultMessageListenerContainer-2) Could not refresh JMS Connection for destination 'shat' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: Failed to create session factory; nested exception is java.lang.IllegalStateException: Server locator is closed (maybe it was garbage collected)
10:44:06,593 ERROR [org.springframework.jms.listener.DefaultMessageListenerContainer] (DefaultMessageListenerContainer-2) Could not refresh JMS Connection for destination 'shat' - retrying using FixedBackOff{interval=5000, currentAttempts=2, maxAttempts=unlimited}. Cause: Failed to create session factory; nested exception is java.lang.IllegalStateException: Server locator is closed (maybe it was garbage collected)
.....
错误提示:JMS 消息侦听器调用程序需要建立共享连接无法刷新目标“shat”的 JMS 连接...服务器定位器已关闭(可能已被垃圾收集)
可能是 ActiveMQ Artemis artemis 1.1.0.wildfly-017 的错误?
有些解决了一些类似的问题?
更新:2016 年 8 月 29 日 - 下午 14:00
如果有人感兴趣...我发现如果你使用 JndiObjectFactoryBean 来查找 JNDI 对象,在这种情况下是 JMS 连接工厂,之前的问题就消失了。通常我会找到一些使用 JndiObjectFactoryBean 的示例,但是对于获取数据库数据源,几乎没有获取 JMS 连接工厂的示例。
更改 MessagingConfiguration 类:
@Bean
public ConnectionFactory connectionFactory() throws NamingException{
ConnectionFactory connectionFactory = InitialContext.doLookup("java:/ConnectionFactory");
return connectionFactory;
}
@Bean
public ConnectionFactory connectionFactory() throws NamingException{
return ConnectionFactory connectionFactory = InitialContext.doLookup("java:/ConnectionFactory");
}
与:
@Bean
public JndiObjectFactoryBean solicitudesConnectionFactory() {
JndiObjectFactoryBean jndi = new JndiObjectFactoryBean();
jndi.setJndiName("java:/ConnectionFactory");
jndi.setLookupOnStartup(true);
jndi.setProxyInterface(ConnectionFactory.class);
return jndi;
}
public ConnectionFactory notificacionesConnectionFactory() {
return new SingleConnectionFactory((ConnectionFactory)solicitudesConnectionFactory().getObject());
}
与 Artemis 的连接也可以正常工作,包括我是否重新部署了应用程序。但是jndi.properties文件没有多用,“Server locator is closed”问题就消失了。
我不知道 JndiObjectFactoryBean 是否正确,但我希望继续使用 jndi.properties 文件。怎么做??
【问题讨论】:
-
也许您需要
DestinationResolver? -
我不明白怎么做。现在我只想使用队列中的消息。然后我将实现发送响应消息的部分。
-
检查这个例子,不要使用:websystique.com/spring/…
-
你救了我的命。
标签: spring jms jndi spring-jms wildfly-10