Search code examples
jmsjboss-eap-7

JMS Temporary Queue - Replies not returning back to client


I'm trying to move away from Weblogic to JBoss, and as such I'm trying to implement the things I was able to implement on Weblogic on JBoss.

One of those things is our notification system where the client sends a request to an MDB and the MDB sends a reply back to the client.

This was a breeze in Weblogic, but on Jboss, nothing seems to work. I keep getting this error:

javax.jms.InvalidDestinationException: Not an ActiveMQ Artemis Destination:ActiveMQTemporaryQueue[da00b1a2-114d-4be9-930d-926fc20c2fce]

Is there something I need to configure on my Jboss?

EDIT

I realise that I probably didn't phrase the question very well.

What happens is this: I have a client and a server MDB (message driven bean). The client sends a message to a queue and waits for a response from the server. The server picks the message from the queue and sends a response to the client, which the client picks up and displays.

On Jboss, messages from the client go smoothly, and the server picks it up, but as soon as the server MDB tries to send a response to the client, that error is thrown.

My client code (excerpt):

int TIME_OUT = 60000;

            //prepare factory
            Properties prop = new Properties();
            prop.setProperty("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
            prop.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
            prop.setProperty("java.naming.provider.url", "http-remoting://remotehost:8080");
            prop.setProperty("java.naming.security.principal", "guest-user")
            prop.setProperty("java.naming.security.credentials", "Password@1")

            String queueConnectionFactory = "jms/RemoteConnectionFactory";

            Context context = new InitialContext(prop);
            QueueConnectionFactory qconFactory = (QueueConnectionFactory) context.lookup(queueConnectionFactory);

            //prepare queue and sessions
            QueueConnection qcon = qconFactory.createQueueConnection(prop.getProperty("java.naming.security.principal"), prop.getProperty("java.naming.security.credentials"));
            QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            Queue queue = (Queue) context.lookup("jms/TestQueue2");

            //create message
            NotificationWrapper wrapper = //object initialised with something
            ObjectMessage om = qsession.createObjectMessage(wrapper);//NotificationWrapper wrapper

            //create producer
            MessageProducer producer = qsession.createProducer(queue);

            //create temporary queue
            TemporaryQueue tempqueue = qsession.createTemporaryQueue();
            om.setJMSReplyTo(tempqueue);

            //start connection
            qcon.start();

            //send message and wait for response
            producer.send(om);
            MessageConsumer consumer = qsession.createConsumer(tempqueue);
            Message callback = consumer.receive(TIME_OUT);

            //print message from server
            if (callback != null) {
                System.out.println("Response received from server. Print here...");
                //message from server
            } else {
                System.out.println("No Response received from server. Problems!!!");
            }

            //close all connections
            if (consumer != null) {
                consumer.close();
            }
            if (producer != null) {
                producer.close();
            }
            if (qsession != null) {
                qsession.close();
            }
            if (qcon != null) {
                qcon.close();
            }

My Server code (excerpt):

@MessageDriven(mappedName = "TestQueue2", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/TestQueue2"),
    @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10")
})
public class ServerSide implements MessageListener {
    private static final QueueConfigProperties queueConfigProp = QueueConfigProperties.getInstance();
    private Context context;
    private QueueConnectionFactory qconFactory;
    private QueueConnection qcon;
    private QueueSession qsession;
    private MessageProducer producer;

    public ServerSide() {
        try {
            initialiseQueueFactory("jms/RemoteConnectionFactory");
            //initialiseQueueFactory("jms/GreenpoleConnectionFactory");
            prepareResponseQueue();
            Properties prop = new Properties();
            prop.setProperty("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
            prop.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
            prop.setProperty("java.naming.provider.url", "http-remoting://remotehost:8080");
            prop.setProperty("java.naming.security.principal", "guest-user")
            prop.setProperty("java.naming.security.credentials", "Password@1")

            String queueConnectionFactory = "jms/RemoteConnectionFactory";

            Context context = new InitialContext(prop);
            QueueConnectionFactory qconFactory = (QueueConnectionFactory) context.lookup(queueConnectionFactory);

            qcon = qconFactory.createQueueConnection(queueConfigProp.getProperty("java.naming.security.principal"), queueConfigProp.getProperty("java.naming.security.credentials"));
            qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        } catch (NamingException | ConfigNotFoundException | IOException | JMSException ex) {
            //error log
        }
    }

    @Override
    public void onMessage(Message message) {
        try {
            if (((ObjectMessage) message).getObject() instanceof NotificationWrapper) {
                //send response
                if (message.getJMSReplyTo() != null) {
                    logger.info("sending response");
                    respondToSenderPositive(message);

                    Response resp = new Response();
                    resp.setRetn(0);
                    resp.setDesc("Notification submitted to queue.");

                    producer = qsession.createProducer(message.getJMSReplyTo());
                    producer.send(qsession.createObjectMessage(resp));

                    producer.send(msg_to_send);
                }
            } else {
                //some message printed here
            }
        } catch (JMSException ex) {
            //error logs
        } catch (Exception ex) {
            //error logs
        }
    }
}

Solution

  • The issue was to do with the configuration of the destination queue which is a remote queue: the client and server are both running on different JVMs. Remote Queues on Jboss are named differently from those on Weblogic.

    The name of a remote queue should be something like this: java:jboss/exported/jms/TestQueue2

    Refer to the JBoss documentation for a more detailed explanation on queues: https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.0/html-single/configuring_messaging/index