0

I have an Apache ActiveMQ Artemis (1.3) instance to which I'm trying to connect from a standalone Spring (4.3.2) application my team is currently working on. It has Spring JTATransactionManager using Atomikos (4.0.4) UserTransactionManager as a provider and during those transactions I need to connect to several resources, including the aforementioned MQ. Following Artemis and Atomikos manuals we've set up ActiveMQConnectionFactory which then gets passed to AtomikosConnectionFactoryBean. It all happens in a Spring container but that doesn't seem to be related to our problem.

It all worked well until I tried to add authentication to the MQ connection. One can set user and password properties on an instance of ActiveMQConnectionFactory, however, they seem to be taken into account only when creating an ordinary connection:

@Override
public Connection createConnection() throws JMSException {
  return createConnection(user, password);
}

@Override
public Connection createConnection(final String username, final String password) throws JMSException {
  return createConnectionInternal(username, password, false, ActiveMQConnection.TYPE_GENERIC_CONNECTION);
}

Atomikos is calling createXAConnection() method (from XAConnectionFactory interface) which, as I see in its implementation, disregards the credentials unless explicitly passed:

@Override
public XAConnection createXAConnection() throws JMSException {
  return createXAConnection(null, null);
}

@Override
public XAConnection createXAConnection(final String username, final String password) throws JMSException {
  return (XAConnection) createConnectionInternal(username, password, true, ActiveMQConnection.TYPE_GENERIC_CONNECTION);
}

This is the way a few other methods in this class work as well, therefore I assume it's not a bug. If so, how should I obtain an authenticated XAConnection? I don't see the possibility of Atomikos calling the overloaded version, looking at its code.

Regards, Jakub

1 Answers1

0

As a workaround, we've decided to wrap ActiveMQConnectionFactory in a class implementing the necessary interface:

public class ActiveMQConnectionFactoryWrapper implements XAConnectionFactory {

  private final ActiveMQConnectionFactory factory;

  public ActiveMQConnectionFactoryWrapper(ActiveMQConnectionFactory factory) {
    this.factory = factory;
  }

  @Override
  public XAConnection createXAConnection() throws JMSException {
    return factory.createXAConnection(factory.getUser(), factory.getPassword());
  }

  @Override
  public XAConnection createXAConnection(String userName, String password) throws JMSException {
    return factory.createXAConnection(userName, password);
  }

  @Override
  public XAJMSContext createXAContext() {
    return factory.createXAContext(factory.getUser(), factory.getPassword());
  }

  @Override
  public XAJMSContext createXAContext(String userName, String password) {
    return factory.createXAContext(userName, password);
  }
}

Other interfaces could be implemented as well, if needs be.