Question

I am trying to setup spring-web to connect to remote Jboss-7.1.1 HornetQ JMS by following this site. But I am getting below error, is there anything I need to add the spring-bean configuration. The current spring-web runs on 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 Producer

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 class

@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();
        }
    }

Jboss's jms module in standalone.xml

<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>

Error

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
Was it helpful?

Solution

It should work, if you replace

<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>

with

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

Doing that, you shouldn't need hornetq dependencies in your pom either, as doing it with a JNDI lookup is implementation agnostic (which is a good thing). The instructions you refer to are about connecting to standalone hornetq server, and in that case you would need the implementations. However, connecting to embedded should not need them.

Assuming, of course, that your spring app is deployed within JBoss having the embedded HornetQ.


Update: ok, so you added that you're actually connecting from Tomcat to JBoss instance. In that case I only see two things wrong:

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

This is wrong as it doesn't match the version shipped with JBoss 7.1.1, and explains your topology error. It should be:

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

Also, when that has been fixed, you'd get a security error as you haven't disabled the security but haven't provided any user credentials to your JMS connection either. Try adding this to your JBoss HornetQ configuration:

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

to disable the security, if you don't want to use it.

I also tested this, this contains the example code in github.


Update2: to be able to use JMS Security, replace this

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

with this

<!-- 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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top