How to use the Generic JMS Adapter to connect to HornetQ from a Progress 4gl session? - Forum - OpenEdge Development - Progress Community

How to use the Generic JMS Adapter to connect to HornetQ from a Progress 4gl session?

 Forum

How to use the Generic JMS Adapter to connect to HornetQ from a Progress 4gl session?

This question is not answered

I've followed the steps listed in this document:

https://community.progress.com/community_groups/openedge_development/m/documents/1986

in order to configure HornetQ as the JMS Provider for OpenEdge. However, I get the following error message in the sonicMQ1.server.log file when trying to run the below sample code in an attempt to send a text message from Progress to HornetQ through the Generic JMS Adapter. It looks like the code is failing at the => RUN setBrokerURL <= statement. Has anybody out there connected to JBoss HornetQ and sent a message from Progress 4gl/abl via the Generic JMS Adapter?


S-0005>(Apr 22, 2016 12:51:44:042) S-0005: receive message queue size set to 10
S-0005>(Apr 22, 2016 12:51:44:042) S-0005: browse message queue size set to 500
S-0005>(Apr 22, 2016 12:51:44:042) : In SessionContainer()
S-0005>(Apr 22, 2016 12:51:44:043) : Looking up ConnectionFactory in JNDI Object Store
S-0005>(Apr 22, 2016 12:51:44:043) : Connection Factory object not found in JNDI Object Store. Creating using jmsProvider.properties file
S-0005>(Apr 22, 2016 12:51:44:043) : Creating JMS connection factory with Broker URL as [ tcp://<HornetQ-Hostname>:5546 ]
S-0005>(Apr 22, 2016 12:51:44:043) 10.3.24.141::sonicMQ1::3620::6e6a1aefaf7ba8f6:-7e0675f2:1543a91dbda:-7fe2
java.lang.Exception: org.hornetq.jms.client.HornetQJMSConnectionFactory class file not mentioned correctly: java.lang.NoSuchMethodException: org.hornetq.jms.client.HornetQJMSConnectionFactory.setBrokerURL(java.lang.String)
    at com.progress.messaging.jms.jms.createConnectionFactory(jms.java:103)
    at com.progress.messaging.jms.jms._connect(jms.java:266)
    at com.progress.javafrom4gl.implementation.JavaServlet.<init>(JavaServlet.java:81)
    at com.progress.javafrom4gl.implementation.ServiceImpl.createConnectionServlet(ServiceImpl.java:106)
    at com.progress.ubroker.broker.ubServerThreadIPC.write(ubServerThreadIPC.java:432)
    at com.progress.ubroker.broker.ubASserverThread.processConnect(ubASserverThread.java:574)
    at com.progress.ubroker.broker.ubServerThread.processEvent(ubServerThread.java:1193)
    at com.progress.ubroker.broker.ubServerThread.mainline(ubServerThread.java:462)
    at com.progress.ubroker.broker.ubServerThread.run(ubServerThread.java:345)

/* Sample code */

DEFINE VARIABLE ptpsession AS HANDLE.
DEFINE VARIABLE messageH AS HANDLE.
DEFINE VARIABLE iping AS INTEGER    NO-UNDO INITIAL 20.
DEFINE VARIABLE lDebug AS LOGICAL.
DEFINE VARIABLE cdate AS CHARACTER NO-UNDO FORMAT "x(16)".
DEFINE VARIABLE ddate AS DATE      NO-UNDO.
/* Creates a session object. */
RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H <Prgs-AppServer-Hostname> -S 5162 -AppService sonicMQ1").
/* Set user credentials. */
RUN setBrokerURL      IN ptpsession (INPUT "tcp://<HornetQ-Hostname>:5546").
RUN setUser           IN ptpsession (INPUT "admin").
RUN setPassword       IN ptpsession (INPUT "admin").

/* Connect to the broker. */
RUN beginSession IN ptpsession.

/* Create a text message */
RUN createTextMessage IN ptpsession (OUTPUT messageH).
ddate = DATE(cdate).
RUN setText IN messageH ("This is test message sent on " + STRING(TIME,"HH:MM:SS")).

/* Send the message on the "main" queue */
RUN sendToQueue IN ptpsession ("main", messageH, ?, ?, ?).   

RUN deleteMessage IN messageH.
RUN deleteSession IN ptpsession.
All Replies
  • When you say you followed the instructions in the document, did you go down the path where you defined the connection via JNDI (p.11 - Locating the Connection Factory Using JNDI)?  [I am looking at your code and think not.  That you are using the setBrokerURL(...) option.]

    I have not used HornetMQ with OpenEdge, but what you are running into is that the JMS specification does not specify how to reference a connection as a URL.  Many JMS providers support the "setBrokerURL([url])" method -- ActiveMQ, Fuse Message Broker, and SonicMQ all do.  

    But others do not (like HornetMQ, or WebSphereMQ.)

    The API-agnostic way to define a connection is via JNDI, and a constructor that returns the javax.jms.Connection, from a lookup name.  

    The OpenEdge Generic JMS Adapter does have an option to not use JNDI, but it has to then use the direct (and non-standard) calls to the implementation of the providers ConnectionFactory (not the jms constructor, but the provider specific one).   The OpenEdge JMS Adapter will try to do this, but it can only do it for the ones it knows specifically about (ActiveMQ, SonicMQ, WebSphereMQ), and it does make a 'guess' that 'setBrokerURL(URL) might exist for other ones.

    That works sometimes, but not for HornetMQ.  

    As I said, I have not used HornetMQ, but if you didn't use JNDI on your first attempt, you might want to try JNDI instead of setBrokerURL().

  • Hi Paulo Lima,

    Could you please share the following files to look at the problem:

    1) $DLC/properties/AdminServerPlugins.properties

    2) $DLC/properties/jmsProvider.properties

    3) $DLC/properties/ubroker.properties

    Thanks,

    Anand.

  • You're correct Bill! I had gone down the other path mentioned in the doc where I was using the AdminServerPlugins.properties file in order to try to locate the Connection Factory.

    Since it doesn't look like HornetQ provides support for the "setBrokerURL([url])" method, I went ahead and changed the method for locating the Connection Factory to use JNDI instead.

    I've created the jmsfromABL.AdminObjectFinder.java class file as per the provided white paper, but it doesn't look like the Generic Adapter is being able to locate my class as I am still seeing the following message in the logs:

    Main  >======================================================================

    Main  >(Apr 25, 2016 16:39:30:063) /u/u01/wrk_11.5_64/sonicMQ1.server.log opened.

    Main  >(Apr 25, 2016 16:39:30:063) : Starts Adapter server logging.

    Main  >(Apr 25, 2016 16:39:30:063) : LoggingLevel set to = 4

    Main  >(Apr 25, 2016 16:39:30:063) : The system property: sonicMQExtensions is set to  false

    Main  >(Apr 25, 2016 16:39:30:064) : The classpath is set to  /u/u01/dlc11.5_64/java/progress.jar:/u/u01/dlc11.5_64/hornetq/lib/hornetq-commons.jar:/u/u01/dlc11.5_64/hornetq/lib/hornetq-core-client.jar:/u/u01/dlc11.5_64/hornetq/lib/hornetq-jms-client.jar:/u/u01/dlc11.5_64/hornetq/lib/jboss-jms-api_1.1_spec.jar:/u/u01/dlc11.5_64/hornetq/lib/netty.jar:/u/u01/dlc11.5_64/hornetq/lib/AdminObjectFinder.jar

    Main  >(Apr 25, 2016 16:39:30:076) : Reading jmsProvider.properties from location : /u/u01/dlc11.5_64/properties/jmsProvider.properties

    Main  >: A public jmsfromABL.AdminObjectFinder class was not found.

    Any idea why the above class is not being found? I've added it to the "/u/u01/dlc11.5_64/hornetq/lib/AdminObjectFinder.jar" file referenced in the classpath as you can see from the above log snippet

  • Here are the contents of my files Anand:

    /*** $DLC/properties/jmsProvider.properties  ***/

    [WebsphereMQ]

    javax.jms.ConnectionFactory=com.ibm.mq.jms.MQConnectionFactory

    javax.jms.QueueConnectionFactory=com.ibm.mq.jms.MQQueueConnectionFactory

    javax.jms.TopicConnectionFactory=com.ibm.mq.jms.MQTopicConnectionFactory

    [ActiveMQ]

    javax.jms.ConnectionFactory=org.apache.activemq.ActiveMQConnectionFactory

    javax.jms.QueueConnectionFactory=org.apache.activemq.ActiveMQConnectionFactory

    javax.jms.TopicConnectionFactory=org.apache.activemq.ActiveMQConnectionFactory

    [HornetQ]

    javax.jms.ConnectionFactory=org.hornetq.jms.client.HornetQJMSConnectionFactory

    javax.jms.QueueConnectionFactory=org.hornetq.jms.client.HornetQJMSConnectionFactory

    javax.jms.TopicConnectionFactory=org.hornetq.jms.client.HornetQJMSConnectionFactory

    /*** $DLC/properties/AdminServerPlugins.properties (only the SonicMQ adapter section) ***/

    #

    # Policy for the 4GL SonicMQ Adapter

    #

    [PluginPolicy.Progress.SonicMQ]

       pluginclasspath=/u/u01/dlc11.5_64/java/progress.jar,/u/u01/dlc11.5_64/hornetq/lib/AdminObjectFinder.jar,/u/u01/dlc11.5_64/hornetq/lib/hornetq-commons.jar,/u/u01/dlc11.5_64/hornetq/lib/hornetq-core-client.jar,/u/u01/dlc11.5_64/hornetq/lib/hornetq-jms-client.jar,/u/u01/dlc11.5_64/hornetq/lib/jboss-jms-api_1.1_spec.jar,/u/u01/dlc11.5_64/hornetq/lib/netty.jar

       classpath=/u/u01/dlc11.5_64/java/progress.jar,/u/u01/dlc11.5_64/hornetq/lib/AdminObjectFinder.jar,/u/u01/dlc11.5_64/hornetq/lib/hornetq-commons.jar,/u/u01/dlc11.5_64/hornetq/lib/hornetq-core-client.jar,/u/u01/dlc11.5_64/hornetq/lib/hornetq-jms-client.jar,/u/u01/dlc11.5_64/hornetq/lib/jboss-jms-api_1.1_spec.jar,/u/u01/dlc11.5_64/hornetq/lib/netty.jar

       jvmargs=-DsonicMQExtensions=false -DjmsProvider=HornetQ

    /*** $DLC/properties/ubroker.properties (only the SonicMQ adapter section) ***/

    #

    # Sample of a SonicMQ Adapter broker

    #

    [Adapter.sonicMQ1]

       appserviceNameList=adapter.progress.jms

       autoStart=1

       brkrLoggingLevel=4

       brokerLogFile=$WRKDIR/sonicMQ1.broker.log

       controllingNameServer=NS1

       description=Sample SonicMQ Adapter broker

       environment=sonicMQ1

       keyAlias=default_server

       portNumber=3620

       srvrLogFile=$WRKDIR/sonicMQ1.server.log

       srvrLoggingLevel=4

       uuid=932.99.999.XXX:1ee77e:cf3bbe3d33:-8030

    Thanks for your help!!!

  • Thank you Paulo Lima for providing the details of the files.

    Quickly, I tried in windows platform with JNDI approach by following the below steps:

    1) Added following details in $DLC/properties/jmsProvider.properties file

    [HornetQ]
    javax.jms.ConnectionFactory=org.hornetq.jms.client.HornetQJMSConnectionFactory
    javax.jms.QueueConnectionFactory=org.hornetq.jms.client.HornetQJMSConnectionFactory
    javax.jms.TopicConnectionFactory=org.hornetq.jms.client.HornetQJMSConnectionFactory

    2) Created AdminObjectFinder.java file to locate the ConnectionFactory and generate AdminObjectFinder.jar with generated class files.

    3) Updated the SonicMQ configuration details in $DLC/properties/AdminServerPlugins.properties file as shown below:

    pluginclasspath=C:\Progress\dlc/java/progress.jar,C:\Softwares\hornetq-2.4.0.Final\lib\hornetq-commons.jar,C:\Softwares\hornetq-2.4.0.Final\lib\hornetq-core-client.jar,C:\Softwares\hornetq-2.4.0.Final\lib\hornetq-jms-client.jar,C:\Softwares\hornetq-2.4.0.Final\lib\jboss-jms-api.jar,C:\Softwares\hornetq-2.4.0.Final\lib\netty.jar,C:\Softwares\hornetq-2.4.0.Final\lib\jnp-client.jar,C:\Softwares\hornetq-2.4.0.Final\lib\AdminObjectFinder.jar
    classpath=C:\Progress\dlc/java/progress.jar,C:\Softwares\hornetq-2.4.0.Final\lib\hornetq-commons.jar,C:\Softwares\hornetq-2.4.0.Final\lib\hornetq-core-client.jar,C:\Softwares\hornetq-2.4.0.Final\lib\hornetq-jms-client.jar,C:\Softwares\hornetq-2.4.0.Final\lib\jboss-jms-api.jar,C:\Softwares\hornetq-2.4.0.Final\lib\netty.jar,C:\Softwares\hornetq-2.4.0.Final\lib\jnp-client.jar,C:\Softwares\hornetq-2.4.0.Final\lib\AdminObjectFinder.jar
    jvmargs=-DsonicMQExtensions=false -DjmsProvider=HornetQ

    4) Increased sonicMQ1 adapter srvrLoggingLevel=5 in $DLC/properties/ubroker.properties file to get information in log files.

    Please find the attached server log (sonicMQ1.server.log) and AdminObjectFinder.java file.

    Hope this helps.

    Thanks,

    Anand.

  • attachments.zip
    Missed the attachment.
     
  • Thanks for giving this a try in your environment Anand! I really appreciate the help!!!

    Just mins ago, I downloaded your AdminObjectFinder.jar file and FTP'd it on to my Linux server. Replaced my AdminObjectFinder.jar file with the one you provided and then I got the following error (which tells me that the class is now being found):

    Main  >(Apr 26, 2016 15:25:59:272) : Reading jmsProvider.properties from location : /u/u01/dlc11.5_64/properties/jmsProvider.properties

    Main  >

    javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory [Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]

    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:674)

    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)

    at javax.naming.InitialContext.init(InitialContext.java:242)

    at javax.naming.InitialContext.<init>(InitialContext.java:216)

    at jmsfromABL.AdminObjectFinder.<init>(AdminObjectFinder.java:29)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)

    at java.lang.Class.newInstance(Class.java:374)

    at com.progress.messaging.jms.jms.getObjectFinders(jms.java:358)

    at com.progress.messaging.jms.jms._startup(jms.java:65)

    at com.progress.javafrom4gl.implementation.ServiceImpl.<init>(ServiceImpl.java:78)

    at com.progress.ubroker.broker.JavaServices.createServices(JavaServices.java:83)

    at com.progress.ubroker.broker.ubroker.main(ubroker.java:154)

    Caused by: java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory

    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)

    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

    at java.security.AccessController.doPrivileged(Native Method)

    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)

    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

    at java.lang.Class.forName0(Native Method)

    at java.lang.Class.forName(Class.java:270)

    at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:63)

    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:671)

    ... 14 more

    Main  >: A  jmsfromABL.AdminObjectFinder object could not be created

    L-3620>(Apr 26, 2016 15:33:03:474) Log Closed

    ======================================================================

    So, after that, I issued the following command in order to update the "jmsfromABL/AdminObjectFinder.class" file within the AdminObjectFinder.jar archive:

    jar uf AdminObjectFinder.jar jmsfromABL/AdminObjectFinder.class

    I wanted to replace your class file with mine since mine uses a different INITIAL_CONTEXT_FACTORY class => "org.jboss.naming.remote.client.InitialContextFactory"

    And it has the correct PROVIDER_URL value pointing to the proper JNDI hostname here in our environment. It has apparently updated the archive just fine. However, when I restarted the AdminServer, I got back to my original error:

    Main  >======================================================================

    Main  >(Apr 26, 2016 15:35:20:240) /u/u01/wrk_11.5_64/sonicMQ1.server.log opened.

    Main  >(Apr 26, 2016 15:35:20:240) : Starts Adapter server logging.

    Main  >(Apr 26, 2016 15:35:20:240) : LoggingLevel set to = 5

    Main  >(Apr 26, 2016 15:35:20:241) : The system property: sonicMQExtensions is set to  false

    Main  >(Apr 26, 2016 15:35:20:241) : The classpath is set to  /u/u01/dlc11.5_64/java/progress.jar:/u/u01/dlc11.5_64/hornetq/lib/hornetq-commons.jar:/u/u01/dlc11.5_64/hornetq/lib/hornetq-core-client.jar:/u/u01/dlc11.5_64/hornetq/lib/hornetq-jms-client.jar:/u/u01/dlc11.5_64/hornetq/lib/jboss-jms-api_1.1_spec.jar:/u/u01/dlc11.5_64/hornetq/lib/netty.jar:/u/u01/dlc11.5_64/hornetq/lib/AdminObjectFinder.jar

    Main  >(Apr 26, 2016 15:35:20:254) : Reading jmsProvider.properties from location : /u/u01/dlc11.5_64/properties/jmsProvider.properties

    Main  >: A public jmsfromABL.AdminObjectFinder class was not found.

    L-3620>(Apr 26, 2016 15:48:44:604) Log Closed

    Main  >======================================================================

    Not sure what is going on here...

  • In order to resolve “java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory” error, we need to add <HornetQHOME>/lib/ jnp-client.jar to classpath and pluginspath under SonicMQ section in $DLC/properties/AdminServerPlugins.properties file.
     
    Instead of updating the AdminObjectFinder.class file in AdminObjectFinder.jar archive, update the AdminObjectFinder.java class with INITIAL_CONTEXT_FACTORY class that you are using and create the jar with updated classes. Use the created jar file for connection factory.
     
    Hope this help!!
     
    Thanks,
    Anand.
     
  • Okay, I was able to work around the issue I was having with the "jar uf AdminObjectFinder.jar jmsfromABL/AdminObjectFinder.class" command I was issuing in order to update my AdminObjectFinder.jar archive with the proper AdminObjectFinder.class file by creating a brand new AdminObjectFinder.jar archive using the OE Studio with the correct AdminObjectFinder.class file (the one that makes use of the "org.jboss.naming.remote.client.InitialContextFactory" instead of "org.jnp.interfaces.NamingContextFactory").

    Now, I am getting the following error when trying to execute my ABL-JMS API code in order to send a text message to HornetQ:

    S-0005>(Apr 27, 2016 14:56:42:121) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb: A JMS session has been created. (9291)

    Thread-29>(Apr 27, 2016 14:56:42:175) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb: send(): Sending a message to a queue

    Thread-29>(Apr 27, 2016 14:56:42:175) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb: send(): Sending a message to: prgs-events-in

    Thread-31>(Apr 27, 2016 14:56:42:175) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb: getNextMessage(): Client requests next message.

    Thread-29>(Apr 27, 2016 14:56:42:176) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb

    javax.jms.JMSException: Please specify a non-zero length byte[]

    at org.hornetq.jms.client.HornetQMessage.setJMSCorrelationIDAsBytes(HornetQMessage.java:380)

    at com.progress.messaging.jms.JMSMessageCreator.setHeaderValues(JMSMessageCreator.java:553)

    at com.progress.messaging.jms.JMSMessageCreator.createMessage(JMSMessageCreator.java:102)

    at com.progress.messaging.jms.SessionContainer.sendToAdptr(SessionContainer.java:592)

    at com.progress.messaging.jms.SessionContainer.sendToAdptr2(SessionContainer.java:727)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at java.lang.reflect.Method.invoke(Method.java:606)

    at com.progress.javafrom4gl.implementation.MethodHolder.invoke(MethodHolder.java:168)

    at com.progress.javafrom4gl.implementation.RequestExecuter$Request.executeRequest(RequestExecuter.java:264)

    at com.progress.javafrom4gl.implementation.RequestExecuter.executeRequest(RequestExecuter.java:70)

    at com.progress.javafrom4gl.implementation.RequestThread.go(RequestThread.java:63)

    at com.progress.javafrom4gl.implementation.RequestThread.run(RequestThread.java:38)

    S-0011>(Apr 27, 2016 14:57:02:846) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb: stop(): Stopping message reception.

    S-0011>(Apr 27, 2016 14:57:02:846) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb: stop(): Message reception stopped.

    S-0011>(Apr 27, 2016 14:57:02:846) 10.3.24.141::sonicMQ1::3620::10034dea67b4f766:5f49e0e1:1545907c13f:-7feb: Client was disconnected without calling deleteSession()! (9294)

    Any idea why I am getting the above error?

    Thanks a lot,

    Paulo

  • Seems like an issue with Generic JMS Adapter connecting to HornetQ Messaging System.

    Please contact with Tech Support Engineer to log an RFA. So that, engineers will take this to resolve the issue.

    Thanks,

    Anand.

  • I'm getting the same error. Can you please post the resolution to this issue?

  • Hi Yokesh,

    As Anand mentioned, please contact Progress Tech Support and log an RFA so that Engineers will take a look into your issue to resolve it.

    Thanks,

    Srinivas Munigala