How to use the Generic JMS Adapter to connect to HornetQ fro

Posted by Paulo Lima on 22-Apr-2016 12:55

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

Posted by Bill Wood on 22-Apr-2016 16:13

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().

Posted by Anand Adike on 25-Apr-2016 07:18

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.

Posted by Paulo Lima on 25-Apr-2016 16:06

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

Posted by Paulo Lima on 25-Apr-2016 16:16

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!!!

Posted by Anand Adike on 26-Apr-2016 05:25

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.

Posted by Anand Adike on 26-Apr-2016 05:44

Missed the attachment.
 

Posted by Paulo Lima on 26-Apr-2016 15:15

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...

Posted by Anand Adike on 27-Apr-2016 00:04

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.
 

Posted by Paulo Lima on 27-Apr-2016 14:10

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

Posted by Anand Adike on 29-Apr-2016 04:01

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.

Posted by Yokesh Parasuraman on 14-Jul-2017 10:29

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

Posted by Srinivas Munigala on 17-Jul-2017 01:06

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

This thread is closed