Search code examples
javaspring-bootjbosshornetq

JMS connection from spring-boot application to JBoss EAP6 HornetQ Topic failed


I have a spring-boot application (1.5.14) that should read from a HornetQ JMS Topic provided by a legacy JBoss EAP 6.4

I know that support for HornetQ has been deprecated since spring 1.4.8. But for now there is no possibity to replace this legacy system.

my dependencies in gradle:

compile("org.springframework.boot:spring-boot-starter-hornetq:1.4.7.RELEASE")

Here's my TopicListener class:

@Component
public class LegacyTopicListener {

 @JmsListener(destination = "jms/topic/legacyTopic", containerFactory = "myFactory")
  public void onReceive(String content) {
    System.out.println(content);
  }
}

Here's my JmsConfiguration class:

@Configuration
@EnableJms
class JmsConfiguration {

  @Bean
  public DefaultJmsListenerContainerFactory myFactory() {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    try {
      factory.setConnectionFactory(connectionFactory());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return factory;
  }  

  @Bean
  public ConnectionFactory connectionFactory() throws Exception {
    HornetQConnectionFactory connectionFactory = new HornetQConnectionFactory(false, 
            transportConfiguration());

    UserCredentialsConnectionFactoryAdapter adapter 
            = new UserCredentialsConnectionFactoryAdapter();
    adapter.setUsername("daUser");
    adapter.setPassword("daPassword");
    adapter.setTargetConnectionFactory(connectionFactory);
    return adapter;
  }

  private TransportConfiguration transportConfiguration() throws Exception {

    Map<String, Object> map = new HashMap<>();
    String host = InetAddress.getLocalHost().getHostAddress();
    map.put("host", host);
    map.put("port", "5647");
    TransportConfiguration configuration = new TransportConfiguration(
            "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory", map);
    return configuration;
  }
}

When I try to connect the JMS Topic I've got this exception:

2019-01-29 17:14:09,975 [ads-1571167970)] ERROR                   o.h.c.client - HQ214013: Failed to decode packet
java.lang.IllegalArgumentException: HQ119032: Invalid type: 0
    at org.hornetq.core.protocol.core.impl.PacketDecoder.decode(PacketDecoder.java:447) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.protocol.ClientPacketDecoder.decode(ClientPacketDecoder.java:56) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.protocol.core.impl.RemotingConnectionImpl.bufferReceived(RemotingConnectionImpl.java:493) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.client.impl.ClientSessionFactoryImpl$DelegatingBufferHandler.bufferReceived(ClientSessionFactoryImpl.java:1712) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.remoting.impl.netty.HornetQChannelHandler.channelRead(HornetQChannelHandler.java:73) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) ~[netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) ~[netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:153) [netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) ~[netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) ~[netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:122) [netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485) [netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452) [netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346) [netty-all-4.0.13.Final.jar:4.0.13.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [netty-all-4.0.13.Final.jar:4.0.13.Final]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]

After that spring-boot try to continue and throw this exception

2019-01-29 17:14:40,009 [           main] INFO       o.a.c.h.Http11NioProtocol - Starting ProtocolHandler ["http-nio-10480"]
2019-01-29 17:14:40,012 [           main] INFO       o.a.t.u.n.NioSelectorPool - Using a shared selector for servlet write/read
2019-01-29 17:14:40,025 [           main] INFO  TomcatEmbeddedServletContainer - Tomcat started on port(s): 10480 (http)
2019-01-29 17:14:40,032 [           main] INFO  .s.StatsApplication - Started StatsApplication in 38.181 seconds (JVM running for 38.711)
2019-01-29 17:14:40,423 [on(4)-127.0.0.1] WARN    o.s.b.a.h.JmsHealthIndicator - Health check failed
2019-01-29 17:14:40,423 [on(4)-127.0.0.1] WARN    o.s.b.a.h.JmsHealthIndicator - Health check failed
javax.jms.JMSException: Failed to create session factory
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:673) ~[hornetq-jms-client-2.4.7.Final.jar:na]
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:112) ~[hornetq-jms-client-2.4.7.Final.jar:na]
    at org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter.doCreateConnection(UserCredentialsConnectionFactoryAdapter.java:178) ~[spring-jms-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter.createConnection(UserCredentialsConnectionFactoryAdapter.java:152) ~[spring-jms-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at org.springframework.boot.actuate.health.JmsHealthIndicator.doHealthCheck(JmsHealthIndicator.java:38) ~[spring-boot-actuator-1.5.14.RELEASE.jar:1.5.14.RELEASE]
    at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:43) ~[spring-boot-actuator-1.5.14.RELEASE.jar:1.5.14.RELEASE]
    at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:68) [spring-boot-actuator-1.5.14.RELEASE.jar:1.5.14.RELEASE]
    at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.java:86) [spring-boot-actuator-1.5.14.RELEASE.jar:1.5.14.RELEASE]
    at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.java:36) [spring-boot-actuator-1.5.14.RELEASE.jar:1.5.14.RELEASE]
    at org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean.getData(DataEndpointMBean.java:46) [spring-boot-actuator-1.5.14.RELEASE.jar:1.5.14.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) [na:1.8.0_144]
    at sun.reflect.GeneratedMethodAccessor351.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) [na:1.8.0_144]
    at javax.management.modelmbean.RequiredModelMBean$4.run(RequiredModelMBean.java:1252) [na:1.8.0_144]
    at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_144]
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) [na:1.8.0_144]
    at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1246) [na:1.8.0_144]
    at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:1085) [na:1.8.0_144]
    at org.springframework.jmx.export.SpringModelMBean.invoke(SpringModelMBean.java:90) [spring-context-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at javax.management.modelmbean.RequiredModelMBean.getAttribute(RequiredModelMBean.java:1562) [na:1.8.0_144]
    at org.springframework.jmx.export.SpringModelMBean.getAttribute(SpringModelMBean.java:109) [spring-context-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:647) [na:1.8.0_144]
    at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678) [na:1.8.0_144]
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1445) [na:1.8.0_144]
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) [na:1.8.0_144]
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) [na:1.8.0_144]
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) [na:1.8.0_144]
    at javax.management.remote.rmi.RMIConnectionImpl.getAttribute(RMIConnectionImpl.java:639) [na:1.8.0_144]
    at sun.reflect.GeneratedMethodAccessor337.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) [na:1.8.0_144]
    at sun.rmi.transport.Transport$1.run(Transport.java:200) [na:1.8.0_144]
    at sun.rmi.transport.Transport$1.run(Transport.java:197) [na:1.8.0_144]
    at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_144]
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196) [na:1.8.0_144]
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) [na:1.8.0_144]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) [na:1.8.0_144]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) [na:1.8.0_144]
    at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_144]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) [na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_144]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_144]
Caused by: java.lang.NullPointerException: null
    at org.hornetq.core.client.impl.ClientSessionFactoryImpl$PingRunnable.send(ClientSessionFactoryImpl.java:1823) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.client.impl.ClientSessionFactoryImpl.getConnection(ClientSessionFactoryImpl.java:1423) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.client.impl.ClientSessionFactoryImpl.getConnectionWithRetry(ClientSessionFactoryImpl.java:1121) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.client.impl.ClientSessionFactoryImpl.connect(ClientSessionFactoryImpl.java:266) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:881) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:669) ~[hornetq-jms-client-2.4.7.Final.jar:na]

Can anybody help? Thanks.

The EAP System is configured via cli:

/subsystem=messaging/hornetq-server=default/jms-topic=legacyTopic:add(entries=["jms/topic/legacyTopic", "java:jboss/exported/jms/topic/legacyTopic"])

JBoss Socket bindings: (Port-offset is 1200)

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
    <socket-binding name="management-native" interface="management" port="${jboss.management.native.port:9999}"/>
    <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
    <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9443}"/>
    <socket-binding name="ajp" port="8009"/>
    <socket-binding name="http" port="8080"/>
    <socket-binding name="https" port="8443"/>
    <socket-binding name="jacorb" interface="unsecure" port="3528"/>
    <socket-binding name="jacorb-ssl" interface="unsecure" port="3529"/>
    <socket-binding name="messaging" port="5445"/>
    <socket-binding name="messaging-group" port="0" multicast-address="${jboss.messaging.group.address:231.7.7.7}" multicast-port="${jboss.messaging.group.port:9876}"/>
    <socket-binding name="messaging-throughput" port="5455"/>
    <socket-binding name="remoting" port="4447"/>
    <socket-binding name="txn-recovery-environment" port="4712"/>
    <socket-binding name="txn-status-manager" port="4713"/>
    <socket-binding name="jgroups-tcp" port="7600"/>
    <socket-binding name="jgroups-tcp-fd" port="57600"/>
</socket-binding-group>

Error after using the port 6645:

Caused by: org.hornetq.api.core.HornetQConnectionTimedOutException: HQ119013: Timed out waiting to receive cluster topology. Group:null
    at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:946) ~[hornetq-core-client-2.4.7.Final.jar:na]
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:669) ~[hornetq-jms-client-2.4.7.Final.jar:na]
    ... 49 common frames omitted

Solution

  • I have found a solution for my problem. But it is a dirty solution.

    JBoss EAP 6.4.x uses HornetQ 2.3.x version. The spring-boot app uses 2.4.x which is a significantly newer release of HornetQ compared to that which ships inside JBoss EAP 6.4.x

    There is a version compatibility issue which does not allow the interoperability of HornetQ 2.3.x and 2.4.x and as such results in a error.

    To solve my problem, i had to ensure that all of my code, client and server side, using the same libraries.

    So i have to change my gradle dependencies:

    compile('org.springframework.boot:spring-boot-starter-hornetq:1.4.7.RELEASE') {
      exclude group: "org.hornetq"
    }
    compile("org.hornetq:hornetq-core-client:2.3.25.SP8-redhat-1")
    compile("org.hornetq:hornetq-jms-client:2.3.25.SP8-redhat-1")
    

    After that, spring-boot app is able to talk to JBoss HornetQ Topic