javajakarta-eejmsactivemq-classicopenmq

How to connect an ActiveMQ producer to an OpenMQ JMS broker


I'm trying to send text messages from a swing heavy client (using Apache ActiveMQ library) to an instance of glassfish server which seems to use OpenMQ as the default JMS provider.

Below the very source basic code I'm using for my client :

try {
    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("jms/SaisieQueueFactory");
    connectionFactory.setBrokerURL("tcp://localhost:27676");
    Connection connection = connectionFactory.createConnection();
    connection.start();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Destination destination = session.createQueue("jms/SaisieQueue");
    MessageProducer producer = session.createProducer(destination);
    producer.setDeliveryMode(DeliveryMode.PERSISTENT);
    TextMessage message = session.createTextMessage("Score + 1");
    producer.send(message);
    session.close();
    connection.close();
} catch(Exception ex) {
    ex.printStackTrace();
}

I got these exceptions :

javax.jms.JMSException: Cannot send, channel has already failed: tcp://127.0.0.1:7676
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62)
    at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1395)
    at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1481)
    at org.apache.activemq.ActiveMQConnection.start(ActiveMQConnection.java:516)
    at testdate.TestDate.main(TestDate.java:44)
Caused by: org.apache.activemq.transport.InactivityIOException: Cannot send, channel has already failed: tcp://127.0.0.1:7676
    at org.apache.activemq.transport.AbstractInactivityMonitor.doOnewaySend(AbstractInactivityMonitor.java:282)
    at org.apache.activemq.transport.AbstractInactivityMonitor.oneway(AbstractInactivityMonitor.java:271)
    at org.apache.activemq.transport.TransportFilter.oneway(TransportFilter.java:85)
    at org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:104)
    at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:68)
    at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:81)
    at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:86)
    at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1366)
    ... 3 more

PS: I'm a beginner with JMS and the Java EE framework


Solution

  • The JMS API definies a java interface and an architecture for messaging, it does not define any specific wire protocol, it could be a carrier pigeon, in memory or any of the common formats (STOMP, OpenWire, AMQP, MQTT).

    Why can't you use Open MQ libraries instead in your client? This is the way JMS is designed. You should only have to switch from the .jar files and change the ConnectionFactory.

    I don't see any reason to switch to ActiveMQ just for the sake of using the ActiveMQ JMS client, since it should be pretty much the same thing as the Open MQ client. There are other reasons to switch though, such as different server side features and what not, but you did not mention that.

    That said, there is bridge component that is able to expose any JMS server over the STOMP protocol (which ActiveMQ supports).

    It's called Stomp Connect and there are some rather old instructions at the OpenMQ page how to use it.

    From there, you should be able to connect with ActiveMQConnection factory specifying STOMP. But I have not really tried this combination myself.