Search code examples
jmsactivemq-artemiswildfly-10

Accessing WildFly's ActiveMQ from standalone client with IBM's SDK


As the title suggests, I'm trying to connect to ActiveMQ running on WildFly 10 from a standalone client. If I use Oracle's SDK, without changing the code or configuration, I'm able to connect, but if, instead, I switch to IBM's SDK, it fails with the following exception:

javax.jms.JMSException: Failed to create session factory
        at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:727)
        at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:233)
        at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:229)
        at pt.sibs.epms.JmsClient.main(JmsClient.java:50)
Caused by: ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ119007: Cannot connect to server(s). Tried with all available servers.]
        at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:777)
        at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:724)
        ... 3 more

My question is: Is this something just not possible and I'm wasting my time or is it just a matter of some extra tweaking?

NOTE: Unfortunately, I've to use IBM's SDK, because the client will run on an AIX machine.

EDIT #1

After doing some bytecode manipulation, I was able to identify the point of divergence.

Oracle's SDK flow of events:

method start() from org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector
                context javax.net.ssl.SSLContext@58c1c010
                this.channelClazzclass io.netty.channel.socket.nio.NioSocketChannel
                isStarted() true
------------------------------------------------------------------------------------------------------------

method doConnect() from io/netty/bootstrap/Bootstrap
                channel.isOpen() true
                regFuture.isDone() true
------------------------------------------------------------------------------------------------------------

method createConnection() from org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector
                future class io.netty.channel.DefaultChannelPromise
                channel class io.netty.channel.socket.nio.NioSocketChannel
                channel.isOpen() true
------------------------------------------------------------------------------------------------------------

method openTransportConnection() from org/apache/activemq/artemis/core/client/impl/ClientSessionFactoryImpl
                connector.isStarted() true
------------------------------------------------------------------------------------------------------------

Everything's working fine.

IBM's SDK flow of events:

method start() from org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector
                context javax.net.ssl.SSLContext@71b0b083
                this.channelClazzclass io.netty.channel.socket.nio.NioSocketChannel
                isStarted() true
------------------------------------------------------------------------------------------------------------

method doConnect() from io/netty/bootstrap/Bootstrap
                channel.isOpen() true
                regFuture.isDone() false
------------------------------------------------------------------------------------------------------------

method doClose() from io/netty/channel/socket/nio/NioSocketChannel
------------------------------------------------------------------------------------------------------------

method createConnection() from org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector
                future class io.netty.channel.DefaultChannelPromise
                channel class io.netty.channel.socket.nio.NioSocketChannel
                channel.isOpen() false
mar 10, 2017 7:59:35 AM org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector createConnection
ERROR: AMQ214016: Failed to create netty connection
java.nio.channels.ClosedChannelException

------------------------------------------------------------------------------------------------------------

method openTransportConnection()from org/apache/activemq/artemis/core/client/impl/ClientSessionFactoryImpl
                connector.isStarted() false
------------------------------------------------------------------------------------------------------------

As you can see, createConnection() fails because the channel isn't open and doClose() from NioSocketChannel is being explicitly invoked. I've changed doClose() to throw and catch an exception so I could see when it's being invoked:

java.lang.Exception: CLOSE INVOKED
                at io.netty.channel.socket.nio.NioSocketChannel.doClose(NioSocketChannel.java:238)
                at io.netty.channel.AbstractChannel$AbstractUnsafe.doClose0(AbstractChannel.java:611)
                at io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:590)
                at io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:534)
                at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.closeOnRead(AbstractNioByteChannel.java:71)
                at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:158)
                at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
                at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
                at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
                at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
                at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
                at java.lang.Thread.run(Thread.java:785)

The close operation happens normally, it is not caused by any exceptional event. Is this a bug?


Solution

  • After several days of investigation, I eventually figured out the problem. I noticed that, although the client was using Java 8, TLSv1 was being used for the handshake (no exception was being thrown). I tried to force TLSv1.2 in several ways, but it was only when I found a poorly documented property that I was able to solve the problem:

    -Dcom.ibm.jsse2.overrideDefaultTLS=true
    

    The property needs to be set on the client side.