Search code examples
spring-bootjmsspring-jmshornetqactivemq-artemis

Spring Boot ActiveMQJMSConnectionFactory to connect to a JBoss EAP 6.1 HornetQ


I'm not sure if what I'm trying to do is possible but basically I'm trying to update the current implementation from HornetQ to ActiveMQ making use of Artemis.

My system is a JMS consumer from the HornetQ.

The current implementation works if I use "HornetQJMSConnectionFactory" but when I change to ActiveMQJMSConnectionFactory it is not able to connect.

In order to test the new implementation, I've spun up a local instance of ActiveMQ and works with the new implementation.

So I've tried multiple different things including forcing protocol =HORNETQ and nothing works.

No compilation error, "only":

ERROR o.s.j.l.DefaultMessageListenerContainer.refreshConnectionUntilSuccessful - Could not refresh JMS Connection for destination 'QueueX' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: Failed to create session factory; nested exception is ActiveMQConnectionTimedOutException[errorType=CONNECTION_TIMEDOUT message=AMQ219013: Timed out waiting to receive cluster topology. Group:null]

Old Implementation

private ConnectionFactory createConnectionFactory(SyncProperties.SmpJmsServer jmsServer) {

    final String className = "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory";

    Map<String, Object> params = new HashMap<String, Object>();
    params.put("host", getJmsHost());
    params.put("port", getJmsPort());
    TransportConfiguration transportConfiguration = new TransportConfiguration(className, params);

    HornetQJMSConnectionFactory hornetQJMSConnectionFactory = new HornetQJMSConnectionFactory(false, transportConfiguration);
    hornetQJMSConnectionFactory.setConnectionTTL(300000);
    hornetQJMSConnectionFactory.setConsumerWindowSize(0);
    UserCredentialsConnectionFactoryAdapter adapter = new UserCredentialsConnectionFactoryAdapter();
    adapter.setTargetConnectionFactory(hornetQJMSConnectionFactory);
    adapter.setUsername(getJmsUsername());
    adapter.setPassword(getJmsPassword());
    CachingConnectionFactory smpCachingConnectionFactory = new CachingConnectionFactory(adapter);
    return smpCachingConnectionFactory;
}

New Implementation

 public ConnectionFactory createActiveMQJMSConnectionFactory()  {

    ActiveMQJMSConnectionFactory activeMQJMSConnectionFactory = new ActiveMQJMSConnectionFactory(false, amqTransportConfiguration());

    activeMQJMSConnectionFactory.setConnectionTTL(300000);
    activeMQJMSConnectionFactory.setConsumerWindowSize(0);

    UserCredentialsConnectionFactoryAdapter adapter = new UserCredentialsConnectionFactoryAdapter();
    adapter.setTargetConnectionFactory(activeMQJMSConnectionFactory);
    adapter.setUsername(getJmsUsername());
    adapter.setPassword(getJmsPassword());
    CachingConnectionFactory smpCachingConnectionFactory = new CachingConnectionFactory(adapter);

    return smpCachingConnectionFactory;
}



@Bean("amqTransportConfiguration")
public TransportConfiguration amqTransportConfiguration() {
    return new TransportConfiguration("org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory", getParams());
}

static Map<String, Object> getParams() {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("host", getJmsHost());
    params.put("port", getJmsPort());
    return params;
}

Thanks for the help.


Solution

  • Although ActiveMQ Artemis is based on the HornetQ code-base an ActiveMQ Artemis client won't be able to talk with a HornetQ broker. Each client sends a protocol/client identifier when it connects. This ID is different between ActiveMQ Artemis clients and HornetQ clients. A HornetQ broker will not recognize the ID sent by the ActiveMQ Artemis client and therefore will not complete a handshake.

    That said, we have worked to ensure that HornetQ clients can still talk to an ActiveMQ Artemis broker. That's what the org.apache.activemq.artemis.core.protocol.hornetq.HornetQProtocolManager provides.

    In any case, upgrading your client won't really do much for you anyway. If you want to upgrade anything I recommend you upgrade EAP or even move to a standalone version of ActiveMQ Artemis so you can get the latest fixes & features.