callback function/async method in JMS api

376 views
Skip to first unread message

Lee Wenger

unread,
Dec 30, 2013, 5:23:04 PM12/30/13
to node...@googlegroups.com
Hey Joe,

I'm trying to use this extension to allow me to talk with a JMS brokver via Java JMS api... e.g. Node to JMS Broker - while some JMS brokers have some extensions that make it easier to communicate to them via node in my case there aren't better options.  There is actually a c api available but I'd rather go the java route as the code becomes more generically reusable for any other broker I might want to connect to.  So i've been able to use your library to connect and send messages but i'm now trying to receive messages and Ideally i'd like to do that via the built in asynchronous patterns that are provided by the api but I'm really not sure how to approach this problem as the method "sink" should ultimately be in java script.

after creating a connection (which I already know is working as I can send messages via the connection) I'm trying to subscribe to a topic - here's the original java code:

            ConnectionFactory factory = new com.xxx.xyzjms.proprietaryConnectionFactory(serverUrl);

            /* create the connection */
            connection = factory.createConnection(userName,password);

            /* create the session */
            session = connection.createSession();

            // lw - actually the same exact problem occurs with the exception callback as it too should actually propogate over to javascript/node side if possible

           /* set the exception listener */
            connection.setExceptionListener(this);

            /* create the destination */
            if (useTopic)
                destination = session.createTopic(name);
            else
                destination = session.createQueue(name);

            System.err.println("Subscribing to destination: "+name);

            /* create the consumer */
            msgConsumer = session.createConsumer(destination);

            /* set the message listener */
            msgConsumer.setMessageListener(this);

            /* start the connection */
            connection.start();

the code for the callback (or what I referred to as the "sink" earlier) is:
    public void onMessage(Message msg)
    {
        try
        {
            System.err.println("Received message: " + msg);
        }
        catch (Exception e)
        {
            System.err.println("Unexpected exception in the message callback!");
            e.printStackTrace();
            System.exit(-1);
        }

    }

also here is the exception callback:
    public void onException(JMSException e)
    {
        /* print the connection exception status */
        System.err.println("CONNECTION EXCEPTION: "+ e.getMessage());
    }

---------
anyway - i'm not sure how to handle these callback type of functions and would appreciate any help.

Joe Ferner

unread,
Dec 30, 2013, 6:23:35 PM12/30/13
to node...@googlegroups.com
Take a look at https://github.com/joeferner/node-java#javaNewProxy assuming the async message callback is an interface it should work. Let me know if that works.

Lee Wenger

unread,
Dec 30, 2013, 11:35:20 PM12/30/13
to node...@googlegroups.com
how do I cast an object to one of its interfaces - I wouldn't think I'd need to do it but it seems I do

var msgProducer = session.createProducerSync(topic);
                          ^
Error: Could not find method "createProducer(com.tibco.tibjms.TibjmsTopic)" on class "class com.tibco.tibjms.TibjmsxSessionImp". Possible matches:
  public javax.jms.MessageProducer com.tibco.tibjms.TibjmsxSessionImp.createProducer(javax.jms.Destination) throws javax.jms.JMSException

so the topic is of type com.tibco.tibjms.TibjmsTopic that implements the javax.jms.Destination interface but the function signature isn't matching up so I think I need to cast
the topic object to javax.jms.Destination  I tried this javascript but no go:

var topicCast = java.import("javax.jms.Destination");
var msgProducer = session.createProducerSync((topicCast)topic);

ideas?

My original version (that was successful) utilized a thin facade object but now I'm trying to utilize the JMS api directly w/o the intermediate layer - less to worry about.

thanks for the help!

Lee Wenger

unread,
Jan 10, 2014, 11:32:05 PM1/10/14
to node...@googlegroups.com
Joe,

I've made some nice progress with this - what a valuable tool you've created.

I'm still experiencing some behavior that I don't understand and would appreciate any thoughts you might have.

I'm using a proxy object created as such:
var myObj = java.newProxy(interfaceType)   to create a new callback object into node.  So I pass this object as a param into a function that sets this object as the callback interface

so, as we discussed, this works great but after getting the call back several times I get an error that it has lost the object and that I need to be using ref() and unref() - I see that this is an exception generated in your c code (util iirc).  so I tried to set the myObj.ref() or even var holderRef = myObj.ref() before I send the object to java to be set as the callback but I have the same behavior (errs out after 8-10 callbacks) so I finally got it to work by adding the code myObj.ref() inside the callback itself.  This behavior doesn't quite make sense to my - why do I need to reinform the JNI side to keep the reference this frequently - and not sure why it works for the first 8-10 calls before it fails - is there some default setting in the jni layer that is getting autodecremented each time a call to a proxy object is called?  This kinda seems like a bug to me - e.g. I can understand needing to manage my own reference on the js side but it seems like the reference should live indefinitely until I release it by calling myObj.unref().  So I should be able to increment the ref() before I set it as the callback then when I'm done, I just decrement the ref count with .unref() and if thats the last reference it should release the proxy object during normal gc.  Maybe my thinking is wrong on this but anyway let me know what you think or how I should be thinking about it.

So a different but similar problem is that the node app is exiting immediately - is there a way to inform node that there is an active background process (like you have when you start an httplistener) and that it should continue to run until we release and/or close the object?  the instantiation of the java object is static and shouldn't hold the app open but as long as I hold reference to a java object created I would think the app should continue to run.

one last thing I'm experiencing is a weird timing/synchronization problem where messages will come into the java bridge in order yet will fire the callback out of order - is there anything you can think of that might explain this?  For the time being I believe I can work around this by requiring explicitly acknowledgements back to the server which will insure that each record is processed by the client before the server will send the next - but there is a performance impact for this so would prefer to not have to use the explicit ack feature and since I can confirm the messages hit the java side in order it seems reasonable that we should be able to insure they hit node in order too.  A lot of what I'm doing is calculating trajectory, momentum, etc so messages out of order is a significant problem.

and, for the record, using your lib, I now have a working bidirectional interface between node.js and a jms broker using the brokers out of box jms client jar file and the little bridge app is dynamically loading the jms connectionFactory object so with this you should be able to use it with any jms provider - you have to add the jms lib to the classpath and then pass the name/loc of the jms jar file and then it should work - i've tested this with TIBCO EMS and with Apache ActiveMQ - will try another or two as time is available.  Once I get it settled a bit more I'll post the code - I might make this another node lib available in npm - node-jms maybe.

Patrick Scanlon

unread,
May 5, 2016, 6:49:56 AM5/5/16
to node-java
Hi Lee, I know this is quite an old post at this point, but did you ever get around to creating any repo of your work? I am looking to use this to connect through a java API to receive messages. Thanks!
Reply all
Reply to author
Forward
0 new messages