0

I'm trying to receive JMS messages from a GlassFish (2.1) server remotely. I have followed the instructions here: http://www.tidytutorials.com/2009/06/jms-example-using-glassfish-and-remote.html and also here: http://www.novell.com/documentation/extend52/Docs/help/MP/jms/tutorial/pointToPoint-1.htm but it doesn't seem to work.

I have created the QueueConnectionFactory sampleFactory and the Queue sampleQueue for testing.

I use the following code to send the message:

HashMap<String,List<String>> values = getValues();
InitialContext context = new InitialContext();

QueueConnectionFactory factory = (QueueConnectionFactory) context.lookup("sampleFactory");
Queue queue = (Queue) context.lookup("sampleQueue");

queueConnection = factory.createQueueConnection();
queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queueSender = queueSession.createSender(queue);
ObjectMessage message = queueSession.createObjectMessage();
message.setObject(values);

queueSender.send(message);

and my client is using the following code :

class JMSListener implements Runnable, MessageListener {

....
public void run() {
    try {
        System.out.println("Started JMS Listener");

        Properties props = new Properties();
        props.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.appserv.naming.S1ASCtxFactory");
        props.put(Context.PROVIDER_URL,"iiop://192.168.38.164:3700");

        Context ctx = new InitialContext(props);


        Queue queue = (Queue) ctx.lookup("sampleQueue");

        QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx.lookup("sampleFactory");

        QueueConnection queueConnection = connectionFactory.createQueueConnection();

        QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        QueueReceiver queueReceiver = queueSession.createReceiver(queue);
        queueConnection.start();

        queueReceiver.setMessageListener(new JMSListener());

        while (true) {
            if(!Thread.currentThread().equals(runner)) break;
            try {
                Thread.sleep(10000);
            } catch (InterruptedException ex) {
                Logger.getLogger(JMSListenerRemote.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("CLOSING!");
        // Don't leak
        queueConnection.close();
    } catch (NamingException ex) {
        Logger.getLogger(Listener.class.getName()).log(Level.SEVERE, null, ex);
    } catch (JMSException ex) {
        Logger.getLogger(Listener.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public void onMessage(Message message) {
    System.out.println("Got a message!");
    try {
        ObjectMessage obj = (ObjectMessage) message;

        HashMap<String, List<String>> values = (HashMap<String, List<String>>) obj.getObject();
        for (Entry<String, List<String>> entry : values.entrySet()) {
            System.out.println("Got key: "+entry.getKey());
        }
    } catch (JMSException ex) {
        Logger.getLogger(Listener.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}

It seems to be able to connect correctly because I added some logging to see if the queue and factory were both ok, and they are. And if I change the name of either the queue or the factory I get an error, so that works as expected.

What doesn't work though is to actually receive the messages. They seem to be sent out ok, but they never reach the client.

Does any one have any ideas as to what might be wrong?

Thanks!

Edit: Oh, and I'm using GlassFish's built in JMS provider.

Petter
  • 4,053
  • 27
  • 33
  • 1
    Update: If I run my client on the same machine as GlassFish and use iiop://127.0.0.1:3700, it works, So the code seems to be correct, but I don't know what needs to be done in order to get it working remotely. – Petter Aug 26 '11 at 11:42
  • Actually, it only works if I'm running under GlassFish as a web-app, running as a stand-alone application doesn't work even from the same machine. – Petter Aug 26 '11 at 12:06
  • Using the IMQAdmin tool can you confirm that your queue really received the message? \glassfish\imq\bin\imqadmin.exe – Preston Aug 26 '11 at 15:22
  • As a coding suggestion, put your queueConnection.close() inside a finally block. Right now the way it is, if you do have an exception, you close call isn't called. – Preston Aug 26 '11 at 15:24
  • The messages were sent, since it worked when running locally. Good idea about closing in the finally block! – Petter Aug 29 '11 at 07:29

2 Answers2

0

What happens if you set the message listener first? (also, you could use same instance)

queueReceiver.setMessageListener(this);
queueConnection.start();

O'Reilly has some examples online, this one is with topics, but should not be that hard to compare/adapt:

http://onjava.com/pub/a/onjava/excerpt/jms_ch2/index.html?page=2

PhilW
  • 741
  • 6
  • 23
  • It didn't seem to help to change the order, or using "this", but I'll have a look at the examples, thanks! – Petter Aug 26 '11 at 10:48
0

OK, I found a solution to this, which isn't really ideal, but it works.

In order to make this work, I needed an additional instance of GlassFish running on the remote machine. On this instance, I had to make some changes in the JMS settings (Configuration -> Java Message Service), I had to set type to REMOTE, and I had to change the default_JMS_Host to use the IP address of the other GlassFish instance.

I could then run the above code as a web application, and receiving messages worked as expected. Still don't know how to make it work if I want it to run as a standalone application.

Petter
  • 4,053
  • 27
  • 33
  • probably you want to use `appclient` to run from the client machine. It will load JAR's, inject, etc, and send the message to the other machine. – Thufir Mar 10 '15 at 00:50