2

我正在尝试通过关注站点来设置 spring-web 以连接到远程 Jboss-7.1.1 HornetQ JMS。但是我遇到了错误,是否需要添加 spring-bean 配置。当前的 spring-web 在 tomcat 上运行。

spring-bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jms="http://www.springframework.org/schema/jms"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="hornetConnectionFactory" class="org.hornetq.jms.client.HornetQJMSConnectionFactory">
        <constructor-arg name="ha" value="false"></constructor-arg>
        <constructor-arg>
            <bean name="transportConfiguration" class="org.hornetq.api.core.TransportConfiguration">
                <constructor-arg
                    value="org.hornetq.core.remoting.impl.netty.NettyConnectorFactory" />
                <constructor-arg>
                    <map key-type="java.lang.String" value-type="java.lang.Object">
                        <entry key="host" value="127.0.0.1" />
                        <entry key="port" value="5445" />
                    </map>
                </constructor-arg>
            </bean>
        </constructor-arg>
    </bean>

    <!-- ConnectionFactory Definition -->
    <bean id="connectionFactory"
        class="org.springframework.jms.connection.CachingConnectionFactory">
        <constructor-arg ref="hornetConnectionFactory"/>
    </bean>

    <!-- Definition of the JMS queue -->
    <bean id="defaultDestination" class="org.hornetq.jms.client.HornetQQueue">
        <constructor-arg index="0" value="DemoQueue"></constructor-arg>

    </bean>

    <bean id="producerTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="defaultDestination" ref="defaultDestination" />
    </bean>
    <bean id="messageSender" class="com.veera.jms.JMSProducer">
    <property name="jmsTemplate" ref="producerTemplate"></property>
    </bean>
</beans>

JMS 生产者

public class JMSProducer {


    @Autowired
    private JmsTemplate jmsTemplate;

    public JmsTemplate getJmsTemplate() {
        return jmsTemplate;
    }

    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    public void sendMessages() throws JMSException{
        jmsTemplate.send(new MessageCreator(){

            @Override
            public Message createMessage(Session session) throws JMSException {
            TextMessage message  = session.createTextMessage("test message from spring");
            message.setStringProperty("text", "Hello World");
                return message;
            }
        });
    }

    public void receiveMessages() throws JMSException{
        System.out.println("Getting message from queue "+ jmsTemplate.receive().getStringProperty("text"));
    }

}

控制器类

@Controller
public class HomeController {

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    @Autowired
    JMSProducer jmsProducer;
    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public void home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
        Calendar cal = Calendar.getInstance();
        try {
            jmsProducer.sendMessages();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

Standalone.xml 中 Jboss 的 jms 模块

<subsystem xmlns="urn:jboss:domain:messaging:1.1">
        <hornetq-server>
            <persistence-enabled>true</persistence-enabled>
            <journal-file-size>102400</journal-file-size>
            <journal-min-files>2</journal-min-files>

            <connectors>
                <netty-connector name="netty" socket-binding="messaging"/>
                <netty-connector name="netty-throughput" socket-binding="messaging-throughput">
                    <param key="batch-delay" value="50"/>
                </netty-connector>
                <in-vm-connector name="in-vm" server-id="0"/>
            </connectors>

            <acceptors>
                <netty-acceptor name="netty" socket-binding="messaging"/>
                <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
                    <param key="batch-delay" value="50"/>
                    <param key="direct-deliver" value="false"/>
                </netty-acceptor>
                <in-vm-acceptor name="in-vm" server-id="0"/>
            </acceptors>

            <security-settings>
                <security-setting match="#">
                    <permission type="send" roles="jmsrole guest"/>
                    <permission type="consume" roles="jmsrole guest"/>
                    <permission type="createNonDurableQueue" roles="jmsrole guest"/>
                    <permission type="deleteNonDurableQueue" roles="jmsrole guest"/>
                </security-setting>
            </security-settings>

            <address-settings>
                <address-setting match="#">
                    <dead-letter-address>jms.queue.DLQ</dead-letter-address>
                    <expiry-address>jms.queue.ExpiryQueue</expiry-address>
                    <redelivery-delay>0</redelivery-delay>
                    <max-size-bytes>10485760</max-size-bytes>
                    <address-full-policy>BLOCK</address-full-policy>
                    <message-counter-history-day-limit>1</message-counter-history-day-limit>
                </address-setting>
            </address-settings>

            <jms-connection-factories>
                <connection-factory name="InVmConnectionFactory">
                    <connectors>
                        <connector-ref connector-name="in-vm"/>
                    </connectors>
                    <entries>
                        <entry name="java:/ConnectionFactory"/>
                    </entries>
                </connection-factory>
                <connection-factory name="RemoteConnectionFactory">
                    <connectors>
                        <connector-ref connector-name="netty"/>
                    </connectors>
                    <entries>
                        <entry name="RemoteConnectionFactory"/>
                        <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                    </entries>
                </connection-factory>
                <pooled-connection-factory name="hornetq-ra">
                    <transaction mode="xa"/>
                    <connectors>
                        <connector-ref connector-name="in-vm"/>
                    </connectors>
                    <entries>
                        <entry name="java:/JmsXA"/>
                    </entries>
                </pooled-connection-factory>
            </jms-connection-factories>

            <jms-destinations>
                <jms-queue name="notificationQueue">
                    <entry name="queue/notificationQueue"/>
                    <entry name="java:jboss/exported/jms/queue/notificationQueue"/>
                </jms-queue>
                <jms-queue name="videoConversionQueue">
                    <entry name="queue/videoConversionQueue"/>
                    <entry name="java:jboss/exported/jms/queue/videoConversionQueue"/>
                </jms-queue>
                <jms-queue name="contentEventQueue">
                    <entry name="queue/contentEventQueue"/>
                    <entry name="java:jboss/exported/jms/queue/contentEventQueue"/>
                </jms-queue>
                <jms-queue name="DemoQueue">
                  <entry name="queue/DemoQueue" />
                </jms-queue>
                <jms-topic name="testTopic">
                    <entry name="topic/test"/>
                    <entry name="java:jboss/exported/jms/topic/test"/>
                </jms-topic>
            </jms-destinations>
        </hornetq-server>
    </subsystem>

POM.xml

<properties>
        <java-version>1.6</java-version>
        <spring.framework.version>3.2.3.RELEASE</spring.framework.version>
        <slf4j.version>1.7.3</slf4j.version>
        <logback.version>1.0.10</logback.version>
        <aspectjrt.version>1.6.7</aspectjrt.version>
        <hornetq.version>2.2.18.Final</hornetq.version>
    </properties>
    <repositories>
        <repository>
            <id>jboss</id>
            <url>http://repository.jboss.org/nexus/content/groups/public/</url>
        </repository>

    </repositories>
    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.framework.version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>


        <dependency>
            <groupId>jboss</groupId>
            <artifactId>jnpserver</artifactId>
            <version>4.2.2.GA</version>
        </dependency>

        <!-- JMS -->
        <dependency>
            <groupId>javax.jms</groupId>
            <artifactId>jms</artifactId>
            <version>1.1</version>
        </dependency>
        <!-- HornetQ Embedded Server -->
        <dependency>
            <groupId>org.hornetq</groupId>
            <artifactId>hornetq-core-client</artifactId>
            <version>${hornetq.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hornetq</groupId>
            <artifactId>hornetq-jms-client</artifactId>
            <version>${hornetq.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hornetq</groupId>
            <artifactId>hornetq-logging</artifactId>
            <version>${hornetq.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.netty</groupId>
            <artifactId>netty</artifactId>
            <version>3.2.9.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.as</groupId>
            <artifactId>jboss-as-jms-client-bom</artifactId>
            <version>7.1.1.Final</version>
            <type>pom</type>
        </dependency>
        <!-- dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging-spi</artifactId> 
            <version>2.0.5.GA</version> </dependency> <dependency> <groupId>org.jboss.javaee</groupId> 
            <artifactId>jboss-jms-api</artifactId> <version>1.1.0.GA</version> <scope>compile</scope> 
            </dependency -->
        <!-- AspectJ -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectjrt.version}</version>
        </dependency>

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>

        <!-- @Inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

错误

18:24:52.065 [http-nio-9090-exec-11] INFO  com.veera.jms.HomeController - Welcome home! The client locale is en_US.
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is javax.jms.JMSException: Failed to create session factory; nested exception is HornetQException[errorCode=3 message=Timed out waiting to receive cluster topology. Group:null]
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
    at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:168)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:469)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:534)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:526)
    at com.veera.jms.JMSProducer.sendMessages(JMSProducer.java:27)
    at com.veera.jms.HomeController.home(HomeController.java:35)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1686)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: javax.jms.JMSException: Failed to create session factory
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:605)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:119)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:114)
    at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:342)
    at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:288)
    at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:225)
    at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:456)
    ... 37 more
Caused by: HornetQException[errorCode=3 message=Timed out waiting to receive cluster topology. Group:null]
    at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:804)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:601)
    ... 44 more
4

1 回答 1

5

它应该工作,如果你更换

<bean name="hornetConnectionFactory" class="org.hornetq.jms.client.HornetQJMSConnectionFactory">
    <constructor-arg name="ha" value="false"></constructor-arg>
    <constructor-arg>
        <bean name="transportConfiguration" class="org.hornetq.api.core.TransportConfiguration">
            <constructor-arg
                value="org.hornetq.core.remoting.impl.netty.NettyConnectorFactory" />
            <constructor-arg>
                <map key-type="java.lang.String" value-type="java.lang.Object">
                    <entry key="host" value="127.0.0.1" />
                    <entry key="port" value="5445" />
                </map>
            </constructor-arg>
        </bean>
    </constructor-arg>
</bean>

<!-- ConnectionFactory Definition -->
<bean id="connectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="hornetConnectionFactory"/>
</bean>

<!-- Definition of the JMS queue -->
<bean id="defaultDestination" class="org.hornetq.jms.client.HornetQQueue">
    <constructor-arg index="0" value="DemoQueue"></constructor-arg>
</bean>

<jee:jndi-lookup id="connectionFactory" jndi-name="java:/JmsXA"/>
<jee:jndi-lookup id="defaultDestination" jndi-name="java:/queue/DemoQueue"/>

这样做,您的 pom 中也不应该需要 hornetq 依赖项,因为使用 JNDI 查找执行此操作与实现无关(这是一件好事)。您参考的说明是关于连接到独立的 hornetq 服务器,在这种情况下,您将需要实现。但是,连接到嵌入式不应该需要它们。

当然,假设您的 spring 应用程序部署在具有嵌入式 HornetQ 的 JBoss 中。


更新:好的,所以您补充说您实际上是从 Tomcat 连接到 JBoss 实例。在那种情况下,我只看到两件事是错误的:

<hornetq.version>2.2.18.Final</hornetq.version>

这是错误的,因为它与 JBoss 7.1.1 附带的版本不匹配,并解释了您的拓扑错误。它应该是:

<hornetq.version>2.2.13.Final</hornetq.version>

此外,当这个问题得到修复后,您会收到一个安全错误,因为您没有禁用安全性,但也没有向您的 JMS 连接提供任何用户凭据。尝试将此添加到您的 JBoss HornetQ 配置中:

<subsystem xmlns="urn:jboss:domain:messaging:1.1">
    <hornetq-server>
        <security-enabled>false</security-enabled> <!-- <- this part -->

禁用安全性,如果您不想使用它。

我也对此进行了测试,包含 github 中的示例代码。


更新 2:为了能够使用 JMS 安全性,替换这个

<!-- ConnectionFactory Definition -->
<bean id="connectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="hornetConnectionFactory"/>
</bean>

有了这个

<!-- ConnectionFactory Definitions -->
<bean id="userCredsConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
   <property name="targetConnectionFactory"><ref bean="hornetConnectionFactory"/></property>
   <property name="username"><value>jmsuser</value></property>
   <property name="password"><value>hornetq</value></property>
   <!-- use credentials of some user you have added in 'jmsrole' group as application
        user in jboss in the above config -->
</bean>

<bean id="connectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="userCredsConnectionFactory"/>
</bean>
于 2013-09-18T14:14:11.357 回答