Connect to WebSphere MQ through JMS API (JMS Adapter)

Posted by Fuelfire on 17-Mar-2017 04:42

Hello, everybody! 

I'm trying to open, get, put, close WebSphere MQ queuе through JMS API. 

I want to connect to the queue manager, open a specific queue, put in her message, get the message and then close and disconnect. Earlier I connected to the MQ through MQ API

With the help of colleagues from this forum, I was able to write a program with the help of which I got the opportunity to put messages in the queue and pick them up. This program is very cumbersome. I made it in the OpenEdge 10.1B, using installed the WebSphere MQ client 7.5 and downloaded the manual "MQSeries Application Programming Interface". It was a test and this solution is not used in our product.

Now I'm using version 11.6.3. Having learned that since version 11.5.1 I can interact with WebSphere MQ without using the SonicMQ (I do not have licenses for this product), I became interested and decided to figure it out.

My task of interacting with WebSphere MQ queues is complicated by the fact that I have to access the queue from the server (not from the client, as in the program I wrote earlier). For these purposes, I plan to use purchased and installed on the database server PAS for OE. In any case, this is how I call the web services: the program on the client calls the application server on which the service call programs run.

So, I started to study the documentation "Messaging and ESB". I made the necessary changes in jmsProvider.properties and AdminServerPlugins.properties in In the %DLC%\properties path:

[PluginPolicy.Progress.SonicMQ]
    pluginclasspath=C:\Program Files\Progress\OpenEdge_11_6/sonic/MQ8.5/lib/sonic_Client.jar,C:\Program Files\Progress\OpenEdge_11_6/sonic/MQ8.5/lib/mgmt_client.jar,C:\Program Files\Progress\OpenEdge_11_6/java/progress.jar,C:\PROGRA~1\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    classpath=C:\Program Files\Progress\OpenEdge_11_6/sonic/MQ8.5/lib/sonic_Client.jar,C:\Program Files\Progress\OpenEdge_11_6/java/progress.jar,C:\PROGRA~1\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ

After that, I began to doubt: there is a WebSphere client on my workstation. But our users work with software using the Client Networking, hosted on a network resource. Probably I should install the WebSphere client on the network? After all, I must somehow run the SonicMQ adapter? On the server in Progress OpenEdge Management I chose the SonicMQ Adapter Resource. But nothing can be created here. Here I am stuck. Do I need to configure something on the server or just make changes to the properties files? Maybe I missed something (did not install it) during the installation of OpenEdge RDBMS?

Can anyone help me? Thanks.

Andrew.

Posted by Anand Adike on 17-Mar-2017 21:28

Hi Fuelfire,
 
Following are the two ways to connect IBM WebSphere MQ.
  • Local Queue Manager
  • Remote Queue Manager (using JNDI approach)
 
Procedure to setup Local Queue Manager:
 
Step 1: Need to update the WebSphereMQ connection factory class names in $DLC/properties/jmsProvider.propeties as shown below:
 
[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
 
Step 2: Update $DLC/properties/AdminServerPlugins.propertes file with WebSphereMQ libraries under [PluginPolicy.Progress.SonicMQ] section as shown below.
 
[PluginPolicy.Progress.SonicMQ]
pluginclasspath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
classpath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ
 
Step 3: We need to start SonicMQ adapter with following command from proenv section.
               proenv>adaptman -i sonicMQ1 -start
Step 4: Provide the quque manager name as a value in Broker-URL in pcode and run it.
 
Procedure to setup Remote Queue Manager:
 
We need to follow below one extra step to connect WebSphere MQ remotely.
 
Develop AdminObjectFinder.java by specifying PROVIDER_URL and generate jar out of it and place it in pluginclasspath and classpath under [PluginPolicy.Progress.SonicMQ].
 
Please find the attached sample pcode.
 
Thanks,
Anand.
 

All Replies

Posted by Fuelfire on 17-Mar-2017 05:48

There are such lines in admserv.log:

[2017/03/17@13:17:48.680+0300] [2] [AdminServer]           Installing plugin: Plugin.SonicMQAdapter (7432)
[2017/03/17@13:17:48.681+0300] [0] [AdminServer]         * Licence check status: Plugin not licensed. (ADMMsg037) (7438)
[2017/03/17@13:17:48.681+0300] [0] [AdminServer]         * Plugin.SonicMQAdapter not installed: Plugin not licensed. (ADMMsg037) (7439)
[2017/03/17@13:17:48.681+0300] [0] [AdminServer]         * Failed to install plugin Plugin.SonicMQAdapter. (7433)

Can I use JMS API to communicate with WebSphere MQ in this configuration? Thanks.

Posted by Anand Adike on 17-Mar-2017 21:28

Hi Fuelfire,
 
Following are the two ways to connect IBM WebSphere MQ.
  • Local Queue Manager
  • Remote Queue Manager (using JNDI approach)
 
Procedure to setup Local Queue Manager:
 
Step 1: Need to update the WebSphereMQ connection factory class names in $DLC/properties/jmsProvider.propeties as shown below:
 
[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
 
Step 2: Update $DLC/properties/AdminServerPlugins.propertes file with WebSphereMQ libraries under [PluginPolicy.Progress.SonicMQ] section as shown below.
 
[PluginPolicy.Progress.SonicMQ]
pluginclasspath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
classpath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ
 
Step 3: We need to start SonicMQ adapter with following command from proenv section.
               proenv>adaptman -i sonicMQ1 -start
Step 4: Provide the quque manager name as a value in Broker-URL in pcode and run it.
 
Procedure to setup Remote Queue Manager:
 
We need to follow below one extra step to connect WebSphere MQ remotely.
 
Develop AdminObjectFinder.java by specifying PROVIDER_URL and generate jar out of it and place it in pluginclasspath and classpath under [PluginPolicy.Progress.SonicMQ].
 
Please find the attached sample pcode.
 
Thanks,
Anand.
 

Posted by Fuelfire on 21-Mar-2017 03:47

Anand, great thanks! Now I have time to continue. I must communicate with remote WebSphereMQ server. And I must develop AdminObjectFinder class. I'm not very good in Java. As I understand, this file allows me to configure the connection settings to the WebSphereMQ server.

Do I understand correctly that  I don't need to install  SonicMQ adapter on the server for working with WebSphere MQ? You write that I must start SonicMQ adapter and specify sonicMQ1 in command. But in my OEM I don't see any sonicMQ adapters. Moreover, I did not install Sonic ESB adapter on the database server. Is it necessary?

I'm looking at an example file in the documentation:

package jmsfromABL;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.TopicConnectionFactory;
import javax.jms.QueueConnectionFactory;
import javax.jms.Topic;
import javax.jms.Queue;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import java.util.Hashtable;
public class AdminObjectFinder{
public Context context = null;

public AdminObjectFinder() throws Exception{
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:/C:/JNDI");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "password");
context = new InitialContext(env);
}
public TopicConnectionFactory getTopicConnectionFactory(String name)
throws Exception {
TopicConnectionFactory factory = null;
factory = (javax.jms.TopicConnectionFactory)context.lookup(name);
return factory;
}
public QueueConnectionFactory getQueueConnectionFactory(String name)
throws Exception {
QueueConnectionFactory factory = null;
factory = (javax.jms.QueueConnectionFactory)context.lookup(name);
return factory;
}
public ConnectionFactory getConnectionFactory(String name)
throws NamingException {
return (ConnectionFactory) context.lookup(name);
}
public Topic getTopic(String name) throws Exception {
Topic topic = null;
Object object = null;
object = context.lookup(name);
if (object != null) {
topic = (javax.jms.Topic) object;
}
return topic;
}
public Queue getQueue(String name) throws Exception {
Queue queue = null;
Object object = null;
object = context.lookup(name);
if (object != null) {
queue = (javax.jms.Queue) object;
}
return queue;
}
public Destination getDestination(String name)
throws NamingException {
return (Destination) context.lookup(name);
}
}

As I understand I must specify in this text URL of MQ Server (PROVIDER_URL), login (SECURITY_PRINCIPAL) and password (SECURITY_CREDENTIALS). Then I must create class with javac and after that pack it in jar. Then I place it in pluginclass and classpath under [PluginPolicy.Progress.SonicMQ].

Is that enough? Or Websphere admin must tell me also INITIAL_CONTEXT_FACTORY ?

Posted by Anand Adike on 21-Mar-2017 06:08

Hi Fuelfire,

AFAIK, we need [PluginPolicy.Progress.SonicMQ] policy plug-in under $DLC/properties/AdminServerPlugins.properties file and Sonic ESB adapter may not be need as we are using MQ system.

In Order to make remote connection with WebSpherMQ follow the below steps:
1) Create Connection factory in WebSphereMQ server
2) Create Client-connection Channel from Channels under Queue Manager
3) Create Client Channel Definition Table (CCDT) and it will be located at <WebSphereMQInstallation>\Qmgrs\RemoteQM\@ipcc\AMQCLCHL.TAB
4) Now, install the WebSphereMQ client on client machine and create .bindings file by providing the location of .TAB file.

Create AdminObjectFinder.java file and specify the location of .bindings file as value to PROVIDER_URL property along with username and password. We can use the INITIAL_CONTEXT_FACTORY value as "com.sun.jndi.fscontext.RefFSContextFactory". Generate the class file from java and packet that class in jar and provide the generated jar file in pluginclasspath and classpath under [PluginPolicy.Progress.SonicMQ].

Hope this helps!!

Thanks,
Anand.

Posted by Fuelfire on 21-Mar-2017 07:37

Sorry, Anand... I'm new in MQ. I don't understand how will I get .bindings file?

I can not follow the steps you proposed - MQ Server is out of my administrative jurisdiction. It's not mine. Perhaps the MQ administrator should give it to me? I do not know what the .bindings file is?

When I wrote a program with structures (I cited the topic above), the MQ admin gave me the following line:

EXTMQUSER.SVRCONN.CH/TCP/vprwmq(1422) and I used it to create an environment variable MQServer. Here, in JNDI approach I've handle another parameters.

At the moment I asked for access to the test queue manager and clarify for myself the unclear points.

Thanks again for the help!

Andrew.

Posted by Anand Adike on 21-Mar-2017 07:56

Hi Fuelfire,

Ask MQ Administrator to provide the Client Channel Definition Table(CCDT) file and use that file to create the .bindings in client machine using the following command.

Syntax:
InitCtx> DEF CF(<connection_factory_name>) + QMGR(<queue_manager_name>) + TRAN(CLIENT) + CHAN(SYSTEM.DEF.SVRCONN) + HOST(<ServerName>) + PORT(<ServerPort>) + CCDTURL(<location of TAB file>)

Example:

InitCtx> DEF CF(RemoteCF) + QMGR(RemoteQM) + TRAN(CLIENT) + CHAN(SYSTEM.DEF.SVRCONN) + HOST(<ServerName>) + PORT(<ServerPort>) + CCDTURL(file:C:/workspace/WMQClient/AMQCLCHL.TAB)

Once .bindings generated, specify the location of .bindings in AdminObjectFinder.java and create jar out of it and use it in classpath and pluginsclasspath.

Hope this helps!!

Thanks,
Anand.

Posted by Fuelfire on 21-Mar-2017 09:00

Anand, I correctly understood that the .bindings file I received from the MQ admin should be copied to the bin directory of the WebSphere MQ Client Installation? I plan to install the MQ client on a network drive for using by clients. They also use client networking from network drive (network Progress installation). If the network drive with the client networking and WebSphere MQ Client is named K, then the path to the binding file will be:

env.put(Context.PROVIDER_URL, "file:/K:/WebSphere MQ/BIN");

Is it right?

Thanks.

Andrew.

Posted by Fuelfire on 22-Mar-2017 04:07

MQ admin sent me a tab file. So, I did the following (I hope this will help the same newbies in the MQ like me):

1. If the MQ client is not installed - you must install it (I have MQ client 7.5 already been installed on the workstation).

2. Open MQ_INSTALLATION_PATH/java/bin/JMSAdmin.config file with text editor and make sure that the directory specified in the PROVIDER_URL exists (in my case the directory C:/JNDI-Directory did not exist and I created it)

3. Run JMSAdmin tool MQ_INSTALLATION_PATH/java/bin/JMSAdmin

4. Run following commands in JMSAdmin tool. Replace <connection_factory_name>, <queue_manager_name>, SYSTEM.DEF.SVRCONN, <ServerName>, <ServerPort> and tab file path with the actual values:

DEF CF(<connection_factory_name>) + QMGR(<queue_manager_name>) + TRAN(CLIENT) + CHAN(SYSTEM.DEF.SVRCONN) + HOST(<ServerName>) + PORT(<ServerPort>) + CCDTURL(<location of TAB file>)

InitCtx> DEF CF(RemoteCF) + QMGR(UNIQM) + TRAN(CLIENT) + CHAN(SWIFTMQ.SVRCONN) + HOST(vplmq12) + PORT(1422) + CCDTURL(file:C:/JNDI-Directory/AMQCLCHL.TAB)

As I understand, I myself define the connection_factory_name. I set it RemoteCF.

5. A file named .bindings has been generated under the directory specified for the PROVIDER_URL parameter (in my case in C:\JNDI-Directory).

Voila, .bindings file is created.

Does the location of .bindings file affect the creation of the class? In other words, should I put this file on a network share or it's only needed to create a class and is not used anywhere else? Thanks.

Posted by Anand Adike on 22-Mar-2017 07:40

We can copy the .bindings file in any location at client machine, but we need to provide the location of .bindings file in AdminObjectFinder.java file. For example, if .bindings file located at C:\remote\ directory then we need to provide the PROVIDER_URL as env.put(Context.PROVIDER_URL, "file://C://remote");

Hope this helps!!

Thanks,
Anand.

Posted by Fuelfire on 22-Mar-2017 09:43

Ok, Anand! You helped me a lot.

Above I wrote the text of the class. Change the line with PROVIDER_URL from

env.put(Context.PROVIDER_URL, "file:/C:/JNDI");

to

env.put(Context.PROVIDER_URL, "file:/C:/JNDI-Directory");

So, we must create AdminObjectFinder.jar. Doing it.

1. Compile AdminObjectFinder.java (command create AdminObjectFinder.class):

%DLC%\jdk\bin\javac AdminObjectFinder.java

2. Pack AdminObjectFinder.class in jar:

%DLC%\jdk\bin\jar cf AdminObjectFinder.jar AdminObjectFinder.class

AdminObjectFinder.jar is created. You must copy it and set the file path in the [PluginPolicy.Progress.SonicMQ] of %DLC%\properties\AdminServerPlugins.properties file (I change it on the server):

[PluginPolicy.Progress.SonicMQ]
    pluginclasspath=C:\Program Files\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar,D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
    classpath=C:\Program Files\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar,D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
    jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ

Posted by Fuelfire on 23-Mar-2017 03:02

Hello, everybody!

I wish everyone a good mood and a productive day :-)

Now I have to write programs for working with queues. Do I need to know what kind of queue model we use? It depends on which of the approaches and procedures should I use? Or it's not important? I assume that our queue server uses the PTP model (but I'll clarify).

Anand, there are a few questions:

1) I see that you use "RUN jms/jmssession.p ". The documentation suggests using "RUN jms/pubsubsession.p" for Publisher/Subscribe and "RUN jms/ptpsession.p" for PTP. How to initialize the session properly?

2) I'm stuck on your example (Producer.p). Where the variable cdate is initialized? Or it's not working example?

3) I see the remark "Set user credentials". Can you show simple code - how I can set user credentials? I thought that the login and password of the user we specify in the class AdminObjectFinder. Later in the documentation I found a description of SetUser and SetPassword. Is this the right procedure?

Thanks!

Posted by Anand Adike on 23-Mar-2017 05:24

Hi Fuelfire,

We should know which model we are going to use before start writing the programs. In any MQ we can send messages using either PTP or Pub-Sub model.

jms/ptpsession.p - will work only with PTP domain
jms/pubsubsession.p - will work only with Pub-Sub domain.
jms/jmssession.p - will work for both PTP and Pub-Sub domains.

2) I'm stuck on your example (Producer.p). Where the variable cdate is initialized? Or it's not working example?
[Anand] - cdate variable is defined in the begin of variable definition section and Producer.p is working sample procedrue to send messages using PTP domain.

Below is example to set the credentials in the procedure.

/* Creates a session object. */
RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H localhost -S 5162 -AppService AD.sonicMQ1").

/* Set user credentials. */
RUN setBrokerURL IN ptpsession (INPUT "TestQueueManager").
RUN setUser IN ptpsession (INPUT "admin" ).
RUN setPassword IN ptpsession (INPUT "admin" ).

Hope this helps!!

Thanks,
Anand.

Posted by Fuelfire on 24-Mar-2017 03:06

Anand, good day! I started sonicMQ1.

How can I determine on which port sonicMQ1 started? I see sonicMQ1.broker.log and sonicMQ1.server.log, but there is no indormation about port number in it. There is no information in admserv.log too.

I run netstat -ao and see that port 5162 is used by java process. But in fact somewhere this information should be logged explicitly?

Thank you.

Posted by Fuelfire on 24-Mar-2017 03:15

The only thing I found in NS1.ns.log:

[17/03/24@10:09:26.718+0300] P-005336 T-main 2 NS NSPlumbing Starting NameServer NS1 rmi://depotest2:20931/NS1 Port = 5162 TimeOut = 35. (8196)

Posted by Srinivas Munigala on 24-Mar-2017 03:39

Hi Fuelfire,

3620 is the default port for sonicMQ1, if you modify it in ubroker.properties file, you can find it in sonicMQ1.broker.log as shown below:

Started listener thread: L-3620 (8043)

It logs in NS1.log file as shown below:

T-NS1 2 NS NSPlumbing Registering Broker 932.99.999.XXX:1ee77e:cf3bbe3d33:-8030 AD.sonicMQ1 XXXXXX.bedford.progress.com/xxx.xx.xx.xx 3620. (8205)

If it is not listing, can you please check whether SonicMQ1 got registered with NS1 or not

Or you can query the SonicMQ1 and find it out as shown below:

Broker Port                    : 3620

Hope, this helps.

Thanks,

Srinivas Munigala

Posted by Fuelfire on 24-Mar-2017 03:54

I plan to work with the MQ through the PAS server.

I wrote a test program that calls the PAS and runs a program on it that writes to the queue and reads from the queue. When I try to write a message to the queue, my program does not respond and in the log I see the following:

[17/03/24@11:32:56.959+0300] P-003524 T-C-0001 2 UB Basic      The client requested ASK version= 1.0  capabilities= denyClientASK,allowServerASK. (13769)
[17/03/24@11:32:56.959+0300] P-003524 T-C-0001 2 UB Basic      The negotiated ASK version= 1.0  capabilities= denyServerASK,denyClientASK.  ASK protocol is disabled for this connection. (15256)
[17/03/24@11:32:56.983+0300] P-003524 T-C-0001 2 UB Basic      Client disconnected : 172.25.197.193. (8534)

I found SonicMQ1 in OEM. I looked up an article in the knowledge base. And in one of them it is said that this is not a error.

I correctly assume that the port selected on the snapshot is the port that I should use in the program. And do I need to change the "AppServer KeepAlive" property?

Posted by Fuelfire on 24-Mar-2017 04:01

Hi, Srinivas! Thank you so much!

Posted by Fuelfire on 24-Mar-2017 04:09

Ok. To make sure that the programs for working with the MQ work correctly, I created a program on the server (this is the database server, the PAS is running here, here SonicMQ1 is launched) and launched it.

/* ***************************  Main Block  *************************** */
DEFINE VARIABLE QueueManager AS CHAR NO-UNDO.
DEFINE VARIABLE QueueName AS CHAR NO-UNDO.
DEFINE VARIABLE CMessage AS CHAR NO-UNDO.

ASSIGN QueueManager = "UNIQM"
                QueueName = "TEST.Q"
                CMessage = "Hello from DepoNet!!!".

DEFINE VARIABLE ptpsession AS HANDLE.
DEFINE VARIABLE messageH AS HANDLE.
DEFINE VARIABLE lDebug AS LOGICAL.

/* Creates a session object. */
RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H localhost -S 3620 -AppService AD.sonicMQ1"). 

/* Set user credentials. */
 
RUN setBrokerURL      IN ptpsession (INPUT QueueManager).

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

/* Create a text message */
RUN createTextMessage IN ptpsession (OUTPUT messageH).

RUN setText IN messageH (CMessage).

/* Publish the message on the "REQUEST" topic */
RUN sendToQueue IN ptpsession (QueueName, messageH, ?, ?, ?).   
RUN deleteMessage IN messageH.
RUN deleteSession IN ptpsession.

MESSAGE "SENT!" VIEW-AS ALERT-BOX.
RETURN "0".

I get the following:

What's wrong?

Posted by Srinivas Munigala on 24-Mar-2017 04:20

You need to provide "-DirectConnect" parameter in the RUN method as shown below:

RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H localhost -S 3620 -AppService AD.sonicMQ1 -DirectConnect").

Otherwise, it tries to connect to the NameServer using the port provided using "-S" parameter

Posted by Fuelfire on 24-Mar-2017 04:30

Thanks, Srinivas. Connection error is gone. Now an error occurs while executing "RUN beginSession IN ptpsession.". Error text: Error connect to the JMS AppServer service.

I'm trying to find a solution in Google.

Posted by Fuelfire on 24-Mar-2017 04:38

Perhaps in [PluginPolicy.Progress.SonicMQ] I must specify the path to WebSphereMQ to lib64 if the interaction with the MQ occurs on the server?

At the moment this section contains the following paths:

[PluginPolicy.Progress.SonicMQ]
    pluginclasspath=C:\Program Files\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar,D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
    classpath=C:\Program Files\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar,D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
    jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ

Posted by Anand Adike on 24-Mar-2017 05:02

Hi Fuelfire,

If sonicMQ1 started properly then we can find sonicMQ1 service name when we query the nameserver from proenv as shown below.

proenv>nsman -i NS1 -q

This will show whether sonicMQ1 is registered with nameserver or not.

Also, we can find sonicMQ1 port number by executing the following command from proenv section.

proenv>adaptman -i sonicMQ1 -q

We can see the value of "Broker Port" in the result.

If sonicMQ1 is not started then check the sonicMQ1 log files or share the files with us.

Thanks,
Anand.

Posted by Anand Adike on 24-Mar-2017 05:07

Hi Fuelfire,

Could you please share the following  files.

1) $DLC/properties/AdminServerPlugins.properties

2) $DLC/properties/ubroker.properties

3) $DLC/properties/jmsProvider.properties

4) $WRKDIR/sonicMQ1.server.log

5) $WRKDIR/sonicMQ1.broker.log

6) Procedures that you are using to send messages to the queue.

Thanks,

Anand.

Posted by Fuelfire on 24-Mar-2017 05:23

Hi, Anand! Of Course! I found a topic where you explain how to set server logging level to 5. I did the same. I started SonicMQ adapter, executed the procedure to connect WebSphereMQ (I do this on the server to exclude the the PAS level). And I see in server log that " A public jmsfromABL.AdminObjectFinder class was not found."

I do not understand what I did wrong?

[View:/cfs-file/__key/communityserver-discussions-components-files/19/5554.Archive.rar:320:240]

Posted by Fuelfire on 24-Mar-2017 05:43

In my opinion, I understood the problem. In AdminObjectFinder.java i wrote:

env.put(Context.PROVIDER_URL, "file:/J:/DPRO_31_10/MQ");

Disk J is the disk on my workstation (a shared folder on the disk D of server).

If the script is running on a server, I should write:

env.put(Context.PROVIDER_URL, "file:/D:/Depo101/DPRO_31_10/MQ");

Perhaps this is the problem?

Posted by Fuelfire on 24-Mar-2017 05:52

I checked my guess. Anyway, when I start SonicMQ1, I see a line in the server log:

Main  >(Mar 24, 2017 13:50:42:662) : Reading jmsProvider.properties from location : C:\Program Files\OpenEdge\properties\jmsProvider.properties
Main  >: A public jmsfromABL.AdminObjectFinder class was not found.

Posted by Anand Adike on 24-Mar-2017 06:19

seems AdminObjectFinder.jar file not available in the specified location in classpath and pluginsclasspath in $DLC/properties/AdminServerPlugins.properties. Could you please check the location of jar file and also increase the server logging level to 5 for sonicMQ1 in $DLC/properties/ubroker.properties file.

Thanks,

Anand.

Posted by Fuelfire on 24-Mar-2017 06:35

During this time I did the following:

1. Change AdminObjectFinder.java 

env.put(Context.PROVIDER_URL, "file://D:/Depo101/DPRO_31_10/MQ");

Now, I have 2 forward slashes "//" after "file:"

2. Create and pack the class.

My AdminObjectFinder.jar is located at D:\Depo101\DPRO_31_10\MQ:

It's location on the server. On this server I run the program test_put.p

The logging level is already increased. I've attached the log with an increased level.

I see this log error: AMQ8568: The native JNI library 'mqjbnd64' was not found. For a client installation this is expected.

Posted by Fuelfire on 24-Mar-2017 08:23

Anand, is it possible to handle exceptions if I call a program through an application server? I cann't get the error "Error connecting to the JMS AppServer service." when I run program test_q.p on workstation and put.p is executed on server by PASOE. Мy test_q.p hangs.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/5228.test_5F00_q.p:320:240]

[View:/cfs-file/__key/communityserver-discussions-components-files/19/1018.Put.p:320:240]

Posted by Anand Adike on 24-Mar-2017 08:36

Hi Fuelfire,

Are you able to start the sonicMQ1 adapter without any problem? could you please let me know whether the adapter created the connection factory?

Please share the sonicMQ1 log file with logging level 5.

Thanks,

Anand.

Posted by Fuelfire on 24-Mar-2017 09:01

How can I determine that adapter create connection factory? My SonicMQ1 startet without any visible problems. But I don't like log SonicMQ start error: 

Main >(Mar 24, 2017 16:53:48:606) : Reading jmsProvider.properties from location : C:\Program Files\OpenEdge\properties\jmsProvider.properties
Main >: A public jmsfromABL.AdminObjectFinder class was not found.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/1526.sonicMQ1.server.log:320:240]

Posted by Fuelfire on 27-Mar-2017 02:22

Hello, Anand. Explain, please - I have a connection to the WebSphere MQ server on my database server (PASOE is running on this server too). I installed MQ Client 7.5 on my server. In the file C:\Program Files (x86)\IBM\WebSphere MQ\java\bin\JMSAdmin.config I have:

INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory

PROVIDER_URL=file:/C:/JNDI-Directory

SECURITY_AUTHENTICATION=none

Does this mean that the .binding file and the AdminObjectFinder.jar file should be in the server's directory C:\JNDI-Directory? Because now the AdminObjectFinder.jar file lies on server'd disk D in the folder D:\Depo101\DPRO_31_10\MQ.

It seems to me that I made a mistake in the jar file or in JMS configuration...

Here is java file and archive.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/AdminObjectFinder.java:320:240]

[View:/cfs-file/__key/communityserver-discussions-components-files/19/AdminObjectFinder.jar:320:240]

I set the log level to 5.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/6523.ubroker.properties:320:240]

[View:/cfs-file/__key/communityserver-discussions-components-files/19/6131.sonicMQ1.server.log:320:240]

Posted by Anand Adike on 27-Mar-2017 04:08

Hi Fuelfire,

We can find the connection factory information in sonicMQ1.server.log as shown below:

Main >======================================================================
Main >(Mar 27, 2017 04:37:25:351) /largedisk/aadike/triage/linux64/117/4jptplongcharptp_WebsphereMQ.dir/sonicMQ1.server.log opened.
Main >(Mar 27, 2017 04:37:25:351) : Starts Adapter server logging.
Main >(Mar 27, 2017 04:37:25:351) : LoggingLevel set to = 5
Main >(Mar 27, 2017 04:37:25:351) : The system property: sonicMQExtensions is set to false
Main >(Mar 27, 2017 04:37:25:351) : The classpath is set to /view/rdl117_linuxx86_64/vobs_prgs/linuxx86_64/dlc/java/progress.jar:/largedisk/aadike/MQShared/java/lib/com.ibm.mqjms.jar:/largedisk/aadike/triage/linux64/117/4jptplongcharptp_WebsphereMQ.dir/AdminObjectFinder.jar
Main >(Mar 27, 2017 04:37:25:390) : Reading jmsProvider.properties from location : /view/rdl117_linuxx86_64/vobs_prgs/linuxx86_64/dlc/properties/jmsProvider.properties
Main >: The AdminObjectFinder.getTopicConnectionFactory method is used for finding the TopicConnectionFactory object. (9301)
Main >: The AdminObjectFinder.getQueueConnectionFactory method is used for finding the QueueConnectionFactory object. (9303)
Main >: The AdminObjectFinder.getTopic method is used for finding the Topic objects. (9305)
Main >: The AdminObjectFinder.getQueue method is used for finding the Queue objects. (9307)

From the log it seems AdminObjectFinder.class file is not available under jmsfromABL package in AdminObjectFinder.jar file.

Follow the below steps to generate AdminObjectFinder.jar file

Step 1: Add the following lines in AdminObjectFinder.java

env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL, "file://D:/Depo101/DPRO_31_10//MQ");
env.put(Context.SECURITY_PRINCIPAL, "swiftmq");
env.put(Context.SECURITY_CREDENTIALS, "swiftmq");

Step 2: compile the java file using following command.
javac -cp jms.jar:.: -d . AdminObjectFinder.java

Step 3: Now, generate the jar file with below command.
jav -cvf AdminObjectFinder.jar jmsfromABL

Step 4: Place the generated jar file in classpath and pluginsclasspath in AdminServerPlugins.properties file.
Step 5: Restart the AdminServer and sonicMQ1 broker.

Please find the attached sample AdminObjectFinder.java.

Hope this helps!!

[View:/cfs-file/__key/communityserver-discussions-components-files/19/8551.AdminObjectFinder.java:320:240]

Thanks,
Anand.

Posted by Fuelfire on 27-Mar-2017 04:25

I can not download the file - page not found. From your answer I see that INITIAL_CONTEXT_FACTORY is changed: from "com.sun.jndi.fscontext.RefFSContextFactory" to "org.jnp.interfaces.NamingContextFactory".  And in PROVIDER_URL you use double slash after "file:" and before "MQ". I'll do it now. I'll keep you posted. Thank you for your help.

Posted by Fuelfire on 27-Mar-2017 04:54

Anand, there are errors on step 2: package javax.jms does not exist.

I used javac in %DLC%\jdk\bin. I run javac on my server.

Last time I generated a class like this:

javac D:\depo101\dpro_31_10\MQ\AdminObjectFinder.java

Probably it's wrong..

Posted by Anand Adike on 27-Mar-2017 06:36

Provide the fully qualified path for jms.jar file instead of absolute path. jms.jar file is available under <MQ_client_installation>/java/lib/jms.jar.

javac -cp <MQ_client_installation>/java/lib/jms.jar -d . AdminObjectFinder.java.

Thanks,

Anand.

Posted by Fuelfire on 27-Mar-2017 06:41

:-( I attached inappropriate screen. I have the same error with the full path:

I used the following command:

proenv>javac -cp C:\progra~2\IBM\WebSph~1\java\lib\jms.jar:.: -d . D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.java

Posted by Anand Adike on 27-Mar-2017 07:39

In windows OS, we need to use semi-colon(;) when we are providing multiple jar file names in classpath. It should work if we replace semi-colon(;) with colon(:).

Thanks,

Anand.

Posted by Fuelfire on 27-Mar-2017 08:25

It worked! I create AdminObjectFinder.jar.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/3225.AdminObjectFinder.jar:320:240]

When I restart AdminService (and restart SonicMQ1 too) I see this error in sonicmq1.server.log whatever:

L-3620>(Mar 27, 2017 15:55:53:765) Log Closed
Main  >======================================================================
Main  >(Mar 27, 2017 15:57:42:665) D:\OpenEdge\WRK\sonicMQ1.server.log opened.
Main  >(Mar 27, 2017 15:57:42:665) : Starts Adapter server logging.
Main  >(Mar 27, 2017 15:57:42:665) : LoggingLevel set to = 5
Main  >(Mar 27, 2017 15:57:42:665) : The system property: sonicMQExtensions is set to  false
Main  >(Mar 27, 2017 15:57:42:666) : The classpath is set to  C:\Program Files\OpenEdge\java\progress.jar;C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar;D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
Main  >(Mar 27, 2017 15:57:42:675) : Reading jmsProvider.properties from location : C:\Program Files\OpenEdge\properties\jmsProvider.properties
Main  >: A public jmsfromABL.AdminObjectFinder class was not found.
S-0001>(Mar 27, 2017 15:59:47:285) 172.25.197.193::sonicMQ1::3620::b984647710b3e528:1d2fd2c7:15b0fd7ea62:-7fec:     Startup Parameters:
    jmsServerName: 
    Point-To-Point     
    brokerURL: UNIQM
    user: swiftmq
    password: swiftmq
    clientID: null
    pingInterval: 
    transactedPublish: false
    transactedReceive: false
    singleMessageAck: false
    symbiontAdapter: false
    jmsDomain: true

S-0001>(Mar 27, 2017 15:59:47:291) S-0001: receive message queue size set to 10
S-0001>(Mar 27, 2017 15:59:47:294) S-0001: browse message queue size set to 500
S-0001>(Mar 27, 2017 15:59:47:294) : In SessionContainer()
S-0001>(Mar 27, 2017 15:59:47:294) : Looking up ConnectionFactory in JNDI Object Store
S-0001>(Mar 27, 2017 15:59:47:294) : Connection Factory object not found in JNDI Object Store. Creating using jmsProvider.properties file
S-0001>(Mar 27, 2017 15:59:47:294) : Creating JMS connection factory with Broker URL as [ UNIQM ]
S-0001>(Mar 27, 2017 15:59:47:611) : Setting Queue Manager UNIQM on Connection Factory Class com.ibm.mq.jms.MQConnectionFactory
S-0001>(Mar 27, 2017 15:59:47:616) 172.25.197.193::sonicMQ1::3620::b984647710b3e528:1d2fd2c7:15b0fd7ea62:-7fec: Using connection values: 26,null,true,,true,false,-1,-1,false,0,false,false,,10000,0,30,false,60,0,20,0,,swiftmq,swiftmq,depotest2,localhost
S-0001>(Mar 27, 2017 15:59:47:690) 172.25.197.193::sonicMQ1::3620::b984647710b3e528:1d2fd2c7:15b0fd7ea62:-7fec
com.ibm.msg.client.jms.DetailedJMSException: JMSFMQ6312: An exception occurred in the Java(tm) MQI.
The Java(tm) MQI has thrown an exception describing the problem. 
See the linked exception for further information.
	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 com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
	at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6863)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6254)
	at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:285)
	at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6189)
	at com.ibm.mq.jms.MQConnectionFactory.createConnection(MQConnectionFactory.java:6245)
	at com.progress.messaging.jms.SessionContainer.createConnection(SessionContainer.java:1512)
	at com.progress.messaging.jms.SessionContainer.init(SessionContainer.java:303)
	at com.progress.messaging.jms.JmsConnection.<init>(JmsConnection.java:39)
	at com.progress.messaging.jms.jms._connect(jms.java:279)
	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:1210)
	at com.progress.ubroker.broker.ubServerThread.mainline(ubServerThread.java:479)
	at com.progress.ubroker.broker.ubServerThread.run(ubServerThread.java:356)
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2495;AMQ8568: The native JNI library 'mqjbnd64' was not found. For a client installation this is expected. [3=mqjbnd64]
	at com.ibm.mq.jmqi.local.LocalMQ$1.run(LocalMQ.java:315)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.ibm.mq.jmqi.local.LocalMQ.initialise_inner(LocalMQ.java:279)
	at com.ibm.mq.jmqi.local.LocalMQ.initialise(LocalMQ.java:242)
	at com.ibm.mq.jmqi.local.LocalMQ.<init>(LocalMQ.java:1205)
	at com.ibm.mq.jmqi.local.LocalServer.<init>(LocalServer.java:206)
	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 com.ibm.mq.jmqi.JmqiEnvironment.getInstance(JmqiEnvironment.java:738)
	at com.ibm.mq.jmqi.JmqiEnvironment.getMQI(JmqiEnvironment.java:672)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6855)
	... 15 more
Caused by: java.lang.UnsatisfiedLinkError: no mqjbnd64 in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
	at java.lang.Runtime.loadLibrary0(Runtime.java:849)
	at java.lang.System.loadLibrary(System.java:1088)
	at com.ibm.mq.jmqi.local.LocalMQ.loadLib(LocalMQ.java:1149)
	at com.ibm.mq.jmqi.local.LocalMQ$1.run(LocalMQ.java:290)
	... 27 more

1. Anand, could you explain, please, why we should use

env.put(Context.PROVIDER_URL, "file://D:/Depo101/DPRO_31_10//MQ");

instead

env.put(Context.PROVIDER_URL, "file://D://Depo101//DPRO_31_10//MQ");

It is suspicious that does not always use a double slash in the path to the directory (PROVIDER_URL). 

I see that the documentation'example uses one slash:

env.put(Context.PROVIDER_URL, "file:/C:/JNDI");

2. I do not like the way to TAB in the bindings file:

RemoteCF/RefAddr/112/Content=file\:D\:/Depo101/DPRO_31_10/MQ/AMQCLCHL.TAB

Is it wrong path or it's Ok?

Posted by Fuelfire on 27-Mar-2017 09:46

I tried to connect WebSphere MQ from the server and from workstation. The difference between this tests - description of recieving error.

When I run program on the server I receive in the sonicmq.server.log:

Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2495;AMQ8568: The native JNI library 'mqjbnd64' was not found. For a client installation this is expected. [3=mqjbnd64]

When I run program on the workstation I receive:

Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2495;AMQ8568: The native JNI library 'mqjbnd' was not found. For a client installation this is expected. [3=mqjbnd]

There is WebSphere MQ Client 7.5 in both cases.

Could anyone tell me where I can downloaded mqjbnd64/mqjbnd library? Thanks.

Posted by Anand Adike on 28-Mar-2017 03:49

Please find the attached samples.zip file that contains the following files:

1) AdminObjectFinder.java

2) .bindings

3)  AMQCLCHL.TAB

From the sonicMQ1.server.log seems that did not created the connection factory. Use the attached files from your reference.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/sample.zip:320:240]

Thanks,

Anand.

Posted by Fuelfire on 28-Mar-2017 05:23

Hi, Anand. I have to make changes to the files. I wrote in AdminObjectFinder.java:

env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:D:\\Depo101\\DPRO_31_10\\MQ"); //works for remote client
env.put(Context.SECURITY_PRINCIPAL, "swiftmq");
env.put(Context.SECURITY_CREDENTIALS, "swiftmq");

What should I change in a binding? Server name, port and path to tab? How correctly to specify a CCDT path in this file directly for Windows of environment? I found this description on the website of IBM:

  1. In the client channel definition table (CCDT) field, enter the explicit path to the file on the server in the form of a URL. For example, if the file was in this path, C:\mquser\ccdt\amqclchl.tab, then the URL for the CCDT field would be file://C:/mquser/ccdt/amqclchl.tab.

Your .bindings file uses the paths for the Unix environment. In my case this is Windows.

Accordingly, I must replace the path:

RemoteTopicCF/RefAddr/53/Content=file\:/largedisk/aadike/triage/linux64/117/4jptplongcharptp_WebsphereMQ.dir/AMQCLCHL.TAB

with:

RemoteTopicCF/RefAddr/53/Content=file\://D\:/Depo101/DPRO_31_10/MQ/AMQCLCHL.TAB

Is it correct?

Our bindings files are different. There are lines like "RemoteCF/RefAddr/" In my generated file. Your file contains lines like "RemoteCF/RefAddr" and lines like "RemoteQueueCF/RefAddr" and lines like "RemoteTopicCF". 

I got the binding file on my workstation via jmsAdmin.bat. Perhaps it should be generated on the server?

In any case, I need to understand how to specify the path to the tab-file in .bindings.

Posted by Anand Adike on 28-Mar-2017 05:31

Hi Fuelfire,

In the .bindings file we need to provide the location of CCDT path. Below is example to specify CCDT file path in windows:

.bindings

RemoteCF/RefAddr/56/Content=file\:C\:/Progress/location/AMQCLCHL.TAB

In my .bindings file I have three different connect factories that is the reason you are able to see multiple connection factories names like RemoteCF, RemoteTopicCF and RemoteQueueCF. I think in your case you might be having only on connection factory.

Thanks,
Anand.

Posted by Fuelfire on 28-Mar-2017 06:25

I must use your tab file? I still left my AMQCLCHL.TAB.

I copy modified AdminObjectFinder.java in D:\Depo101\DPRO_31_10\MQ on the server.

Note how I specified the path to the directory:

env.put(Context.PROVIDER_URL, "file:D:\\Depo101\\DPRO_31_10\\MQ"); //works for remote client

This directory (d:\depo101\DPRO_31_10\MQ) contains my AMQCLCHL.TAB and .bindings. Then I compiled java and packed it in jar (i use %dlc%\jdk\bin on the server):

javac -cp C:\progra~2\IBM\WebSph~1\java\lib\jms.jar;.; -d . D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.java

jar -cvf d:\depo101\DPRO_31_10\MQ\AdminObjectFinder.jar C:\Progra~1\OpenEdge\jdk\bin\jmsfromABL

Here is the files:

[View:/cfs-file/__key/communityserver-discussions-components-files/19/2063.AdminObjectFinder.java:320:240]

[View:/cfs-file/__key/communityserver-discussions-components-files/19/4130.AdminObjectFinder.jar:320:240]

Then I stoped AdminService on server and after a few minutes I started it. My sonicMQ1 adapter is configured to autostart:

Then I check the sonicMQ1.server.log:

Main >======================================================================
Main >(Mar 28, 2017 14:19:14:599) D:\OpenEdge\WRK\sonicMQ1.server.log opened.
Main >(Mar 28, 2017 14:19:14:599) : Starts Adapter server logging.
Main >(Mar 28, 2017 14:19:14:599) : LoggingLevel set to = 5
Main >(Mar 28, 2017 14:19:14:599) : The system property: sonicMQExtensions is set to false
Main >(Mar 28, 2017 14:19:14:599) : The classpath is set to C:\Program Files\OpenEdge\java\progress.jar;C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar;D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
Main >(Mar 28, 2017 14:19:14:635) : Reading jmsProvider.properties from location : C:\Program Files\OpenEdge\properties\jmsProvider.properties
Main >: A public jmsfromABL.AdminObjectFinder class was not found.

Nothing changed!

Do you see a mistake in my actions?

I'll try to use your binding file now. I'm afraid to make a mistake when editing it. Anyway, I'll try. I'll keep you informed.

Posted by Fuelfire on 28-Mar-2017 06:33

Anand, please check my program. May be my program is not good? And the reason is not in the configuration.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/test_5F00_put.p:320:240]

Posted by Anand Adike on 28-Mar-2017 06:46

Could you please share the below updated files:

1) AdminServerPlugnis.properties

2) jmsProvider.proerties

3) AdminObjectFinder.java

4) AMQCLCHL.TAB

5) .bindings

6) Procedures that you are using to publish/consume the messages.

Thanks,

Anand.

Posted by Fuelfire on 28-Mar-2017 07:29

Ok.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/0334.Archive.rar:320:240]

AdminObjectFinder.java, AdminObjectFinder.jar, AMQCLCHL.TAB and .bindings files are located in D:\Depo101\DPRO_31_10\MQ:

My program that put message in query is test_put.p.

Posted by Fuelfire on 28-Mar-2017 09:42

Anand, I generated the .binding file on your tab-file. I copied 2 files in the server's directory D:\Depo101\DPRO_31_10\MQ, but  there is the same result:

A public jmsfromABL.AdminObjectFinder class was not found.

S-0001>(Mar 28, 2017 17:37:53:787) : Looking up ConnectionFactory in JNDI Object Store
S-0001>(Mar 28, 2017 17:37:53:788) : Connection Factory object not found in JNDI Object Store. Creating using jmsProvider.properties file
S-0001>(Mar 28, 2017 17:37:53:788) : Creating JMS connection factory with Broker URL as [ UNIQM ]

I don't know what's wrong... :-(

Posted by Fuelfire on 29-Mar-2017 01:37

Hi, Anand!

I do not remember if I rebooted the server after installing the MQ Client. I restarted it in the morning. Then I recreated the AdminObjecttFinder.jar (jmsfromABL directory was created in D:\Depo101\DPRO_31_10\MQ). Without a good result. The error is the same.

I think my AdminObjectFinder.jar is not correct. Look here, please:

It seems to me that in the jar there must be a directory "jmsfromABL" without absolute path... Can you attach any AdminObjectFinder.jar? 

Posted by Fuelfire on 29-Mar-2017 02:54

It seems to be better already :-) I compiled and packed this way:

That's what's in the log when sonicMQ1 starts:

Main  >======================================================================
Main  >(Mar 29, 2017 10:47:35:091) D:\OpenEdge\WRK\sonicMQ1.server.log opened.
Main  >(Mar 29, 2017 10:47:35:091) : Starts Adapter server logging.
Main  >(Mar 29, 2017 10:47:35:091) : LoggingLevel set to = 5
Main  >(Mar 29, 2017 10:47:35:091) : The system property: sonicMQExtensions is set to  false
Main  >(Mar 29, 2017 10:47:35:091) : The classpath is set to  C:\Program Files\OpenEdge\java\progress.jar;C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar;D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
Main  >(Mar 29, 2017 10:47:35:124) : Reading jmsProvider.properties from location : C:\Program Files\OpenEdge\properties\jmsProvider.properties
Main  >: The AdminObjectFinder.getTopicConnectionFactory method is used for finding the TopicConnectionFactory object. (9301)
Main  >: The AdminObjectFinder.getQueueConnectionFactory method is used for finding the QueueConnectionFactory object. (9303)
Main  >: The AdminObjectFinder.getTopic method is used for finding the Topic objects. (9305)
Main  >: The AdminObjectFinder.getQueue method is used for finding the Queue objects. (9307)

But when I start test_put.p Ireceive:

S-0001>(Mar 29, 2017 10:51:37:538) 172.25.197.193::sonicMQ1::3620::fd5fb9d0e955d13d:2a8ce8b1:15b1908b614:-7fec:     Startup Parameters:
    jmsServerName: 
    Point-To-Point     
    brokerURL: UNIQM
    user: swiftmq
    password: swiftmq
    clientID: null
    pingInterval: 
    transactedPublish: false
    transactedReceive: false
    singleMessageAck: false
    symbiontAdapter: false
    jmsDomain: true

S-0001>(Mar 29, 2017 10:51:37:543) S-0001: receive message queue size set to 10
S-0001>(Mar 29, 2017 10:51:37:545) S-0001: browse message queue size set to 500
S-0001>(Mar 29, 2017 10:51:37:546) : In SessionContainer()
S-0001>: Connection factory with the name UNIQM not found in JNDI store. Printing stack trace: 
S-0001>
java.lang.reflect.InvocationTargetException
	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.messaging.jms.jms.getConnFactory(jms.java:516)
	at com.progress.messaging.jms.jms._connect(jms.java:240)
	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:1210)
	at com.progress.ubroker.broker.ubServerThread.mainline(ubServerThread.java:479)
	at com.progress.ubroker.broker.ubServerThread.run(ubServerThread.java:356)
Caused by: javax.naming.NameNotFoundException: UNIQM
	at com.sun.jndi.fscontext.RefFSContext.getObjectFromBindings(RefFSContext.java:400)
	at com.sun.jndi.fscontext.RefFSContext.lookupObject(RefFSContext.java:327)
	at com.sun.jndi.fscontext.RefFSContext.lookup(RefFSContext.java:146)
	at com.sun.jndi.fscontext.FSContext.lookup(FSContext.java:127)
	at javax.naming.InitialContext.lookup(InitialContext.java:411)
	at jmsfromABL.AdminObjectFinder.getConnectionFactory(AdminObjectFinder.java:45)
	... 13 more
S-0001>(Mar 29, 2017 10:51:37:553) : Looking up ConnectionFactory in JNDI Object Store
S-0001>(Mar 29, 2017 10:51:37:553) : Connection Factory object not found in JNDI Object Store. Creating using jmsProvider.properties file
S-0001>(Mar 29, 2017 10:51:37:553) : Creating JMS connection factory with Broker URL as [ UNIQM ]
S-0001>(Mar 29, 2017 10:51:37:937) : Setting Queue Manager UNIQM on Connection Factory Class com.ibm.mq.jms.MQConnectionFactory
S-0001>(Mar 29, 2017 10:51:37:942) 172.25.197.193::sonicMQ1::3620::fd5fb9d0e955d13d:2a8ce8b1:15b1908b614:-7fec: Using connection values: 26,null,true,,true,false,-1,-1,false,0,false,false,,10000,0,30,false,60,0,20,0,,swiftmq,swiftmq,depotest2,localhost
S-0001>(Mar 29, 2017 10:51:38:016) 172.25.197.193::sonicMQ1::3620::fd5fb9d0e955d13d:2a8ce8b1:15b1908b614:-7fec
com.ibm.msg.client.jms.DetailedJMSException: JMSFMQ6312: An exception occurred in the Java(tm) MQI.
The Java(tm) MQI has thrown an exception describing the problem. 
See the linked exception for further information.
	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 com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
	at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6863)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6254)
	at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:285)
	at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6189)
	at com.ibm.mq.jms.MQConnectionFactory.createConnection(MQConnectionFactory.java:6245)
	at com.progress.messaging.jms.SessionContainer.createConnection(SessionContainer.java:1512)
	at com.progress.messaging.jms.SessionContainer.init(SessionContainer.java:303)
	at com.progress.messaging.jms.JmsConnection.<init>(JmsConnection.java:39)
	at com.progress.messaging.jms.jms._connect(jms.java:279)
	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:1210)
	at com.progress.ubroker.broker.ubServerThread.mainline(ubServerThread.java:479)
	at com.progress.ubroker.broker.ubServerThread.run(ubServerThread.java:356)
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2495;AMQ8568: The native JNI library 'mqjbnd64' was not found. For a client installation this is expected. [3=mqjbnd64]
	at com.ibm.mq.jmqi.local.LocalMQ$1.run(LocalMQ.java:315)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.ibm.mq.jmqi.local.LocalMQ.initialise_inner(LocalMQ.java:279)
	at com.ibm.mq.jmqi.local.LocalMQ.initialise(LocalMQ.java:242)
	at com.ibm.mq.jmqi.local.LocalMQ.<init>(LocalMQ.java:1205)
	at com.ibm.mq.jmqi.local.LocalServer.<init>(LocalServer.java:206)
	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 com.ibm.mq.jmqi.JmqiEnvironment.getInstance(JmqiEnvironment.java:738)
	at com.ibm.mq.jmqi.JmqiEnvironment.getMQI(JmqiEnvironment.java:672)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6855)
	... 15 more
Caused by: java.lang.UnsatisfiedLinkError: no mqjbnd64 in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
	at java.lang.Runtime.loadLibrary0(Runtime.java:849)
	at java.lang.System.loadLibrary(System.java:1088)
	at com.ibm.mq.jmqi.local.LocalMQ.loadLib(LocalMQ.java:1149)
	at com.ibm.mq.jmqi.local.LocalMQ$1.run(LocalMQ.java:290)
	... 27 more

Posted by Fuelfire on 29-Mar-2017 03:15

Just in case, I'll attach a screenshot with the commands that make the correct jar (directory "1" contains only directory "jmsfromABL").

Posted by Fuelfire on 29-Mar-2017 04:17

I read the error "Connection factory with the name UNIQM not found in JNDI store". I replace this line in program:

RUN setBrokerURL IN ptpsession (INPUT QueueManager).

with:

RUN setBrokerURL IN ptpsession ("RemoteCF").

I gor another error when I run test_put.p:

S-0003>(Mar 29, 2017 11:45:23:669) 172.25.197.193::sonicMQ1::3620::a67accc527088e3b:4fc2a024:15b19242fe1:-7fc4:     Startup Parameters:
    jmsServerName: 
    Point-To-Point     
    brokerURL: RemoteCF
    user: swiftmq
    password: swiftmq
    clientID: null
    pingInterval: 
    transactedPublish: false
    transactedReceive: false
    singleMessageAck: false
    symbiontAdapter: false
    jmsDomain: true

S-0003>(Mar 29, 2017 11:45:23:669) S-0003: receive message queue size set to 10
S-0003>(Mar 29, 2017 11:45:23:670) S-0003: browse message queue size set to 500
S-0003>(Mar 29, 2017 11:45:23:670) : In SessionContainer()
S-0003>(Mar 29, 2017 11:45:23:685) : Looking up ConnectionFactory in JNDI Object Store
S-0003>(Mar 29, 2017 11:45:23:685) 172.25.197.193::sonicMQ1::3620::a67accc527088e3b:4fc2a024:15b19242fe1:-7fc4: Using connection values: 26,null,true,,true,false,-1,-1,false,0,false,false,,10000,0,30,false,60,0,20,0,,swiftmq,swiftmq,depotest2,localhost
S-0003>(Mar 29, 2017 11:45:23:925) 172.25.197.193::sonicMQ1::3620::a67accc527088e3b:4fc2a024:15b19242fe1:-7fc4
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2020: Failed to connect to queue manager 'UNIQM' with connection mode 'Client' and supplied CCDT URL 'file:D:/Depo101/DPRO_31_10/MQ/AMQCLCHL.TAB', see linked exception for more information.
Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.
	at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:585)
	at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:221)
	at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:327)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6876)
	at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6254)
	at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:285)
	at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6189)
	at com.ibm.mq.jms.MQConnectionFactory.createConnection(MQConnectionFactory.java:6245)
	at com.progress.messaging.jms.SessionContainer.createConnection(SessionContainer.java:1512)
	at com.progress.messaging.jms.SessionContainer.init(SessionContainer.java:303)
	at com.progress.messaging.jms.JmsConnection.<init>(JmsConnection.java:39)
	at com.progress.messaging.jms.jms._connect(jms.java:279)
	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:1210)
	at com.progress.ubroker.broker.ubServerThread.mainline(ubServerThread.java:479)
	at com.progress.ubroker.broker.ubServerThread.run(ubServerThread.java:356)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2423' ('MQRC_CLIENT_CHANNEL_CONFLICT').
	at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:209)
	... 17 more

May be I must exclude "CHAN(SWIFTMQ.SVRCONN)" from define command when I generate .bindings?

Posted by Anand Adike on 30-Mar-2017 00:40

Hi Fuelfire,

Thank you for sharing the files.

Looked at the files and observed that the jar (AdminObjectFinder.jar)  that you are using is an invalid jar file. Please find the attached sample AdminObjectFinder.java and AdminObjectFinder.jar for your reference.

Also, observed that you are using PTP domain from ABL client to publish the messages. What type of connection factory have you created in IBM WebSphereMQ?

[View:/cfs-file/__key/communityserver-discussions-components-files/19/samples.zip:320:240]


Thanks,
Anand.

Posted by Fuelfire on 30-Mar-2017 01:38

Hi, Anand. Glad to see you on the forum. As for the creation of the jar file, it's now clear to me. I somewhere downloaded AdminObjectFinder with the class jmsfrom4GL and saw that the contents of the archive are different.

Now about the Connection Factory. When I asked the administrator of the MQ what connection factory name I used for Define command, he told me that this name is given arbitrarily. That's why I used, as in your example, RemoteCF. Probably this parameter is set on the MQ server and the admin should tell me its name? Thanks!

Posted by Fuelfire on 30-Mar-2017 02:08

Carefully read your question again. My define command is:

DEF CF(RemoteCF) + QMGR(UNIQM) + TRAN(CLIENT) + CHAN(SWIFTMQ.SVRCONN) + HOST(vplmq12) + PORT(1422) + CCDTURL(file:D:/Depo101/DPRO_31_10/MQ/AMQCLCHL.TAB)

What I should to do and where? (MQ client, MQ server).

Posted by Fuelfire on 30-Mar-2017 03:45

Sending the name of the connection factory (RemoteCF) to the setBrokerURL I avoid the error:

Connection factory with the name UNIQM not found in JNDI store

But I get another error:

JMSWMQ2020: Failed to connect to queue manager 'UNIQM' with connection mode 'Client' and supplied CCDT URL 'file:D:/Depo101/DPRO_31_10/MQ/AMQCLCHL.TAB', see linked exception for more information.

...

Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2423' ('MQRC_CLIENT_CHANNEL_CONFLICT').

What should I pass into the procedure setBrokerURL: the name of the connection factory or the name of the queue manager?

Posted by Anand Adike on 30-Mar-2017 03:51

When we are creating connection factory in WebSphereMQ server there is an option to select which model we are going to use to send messages with created connection factory like PTP or Pub-Sub or any one these. If we create ptp connection factory then we need to use ptp domain in ABL and similary for pub-sub. In case, connection factory created to use both ptp and pub-sub then we have to use jms domain in ABL client.

did you try to use the AdminObjectFinder.jar that i shared with you? if not please try to use it once. As i modified PROVIDER_URL in AdminObjectFinder.java.

Thanks,

Anand.

Posted by Fuelfire on 30-Mar-2017 04:04

Sorry, I did not see that you corrected the file and found that they are the same. I replaced the jar file on the server, restarted AdminService and see the sonicMQ1.server.log:

Main  >======================================================================
Main  >(Mar 30, 2017 12:00:26:649) D:\OpenEdge\WRK\sonicMQ1.server.log opened.
Main  >(Mar 30, 2017 12:00:26:649) : Starts Adapter server logging.
Main  >(Mar 30, 2017 12:00:26:649) : LoggingLevel set to = 5
Main  >(Mar 30, 2017 12:00:26:649) : The system property: sonicMQExtensions is set to  false
Main  >(Mar 30, 2017 12:00:26:649) : The classpath is set to  C:\Program Files\OpenEdge\java\progress.jar;C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar;D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
Main  >(Mar 30, 2017 12:00:26:692) : Reading jmsProvider.properties from location : C:\Program Files\OpenEdge\properties\jmsProvider.properties
Main  >: A public jmsfromABL.AdminObjectFinder class was not found.

Again, the old error.

Posted by Anand Adike on 30-Mar-2017 04:10

replace the following line in AdminObjectFinder.java file and regenerate the jar file.

from:

env.put(Context.PROVIDER_URL, "file:D:\\Depo101\\DPRO_31_10\\MQ");

to:

env.put(Context.PROVIDER_URL, "file:/D:\\Depo101\\DPRO_31_10\\MQ");

Thanks,

Anand.

Posted by Fuelfire on 30-Mar-2017 04:26

Compiled and packed your file myself and re-started the service AdminService again. There is no error after service starting. What should I pass to SetBrokerURL: queue manager name or connection factory name? When I passed queue manager name UNIQM i receive old error. I changed the line in program with

RUN setBrokerURL IN ptpsession ("RemoteCF").

and run. There are the same errors, which  I have already described to you. I attached the log.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/1460.sonicMQ1.server.log:320:240]

Posted by Anand Adike on 30-Mar-2017 07:29

We need to provide Connection factory name for JNDI approach, otherwise we can use queue manager name if everything is running in single machine. In your case, we need to use connection factory name in setBrokerURL.

Thanks,

Anand.

Posted by Fuelfire on 30-Mar-2017 08:09

I read this article and suggested that a number of parameters such as the channel name is already defined in the AMQCLCHL.TAB. I decided to regenerate .bindings file without specifying CCDTURL:

DEF CF(RemoteCF) + QMGR(UNIQM) + TRAN(CLIENT) + CHAN(SWIFTMQ.SVRCONN) + HOST(vplmq12) + PORT(1422)

Then I compiled and packed my class. I restarted AdminService and run this program:

/* ***************************  Main Block  *************************** */
DEFINE VARIABLE QueueManager AS CHAR NO-UNDO.
DEFINE VARIABLE QueueName AS CHAR NO-UNDO.
DEFINE VARIABLE CMessage AS CHAR NO-UNDO.

ASSIGN QueueManager = "UNIQM"
                QueueName = "TEST.Q"
                CMessage = "Hello from DepoNet!!!".

DEFINE VARIABLE ptpsession AS HANDLE.
DEFINE VARIABLE messageH AS HANDLE.
DEFINE VARIABLE lDebug AS LOGICAL.

/* Creates a session object. */
RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H localhost -S 3620 -AppService AD.sonicMQ1 -DirectConnect"). 

/* Set user credentials. */
 
RUN setBrokerURL      IN ptpsession ("RemoteCF").

RUN setUser           IN ptpsession (INPUT "swiftmq").

RUN setPassword       IN ptpsession (INPUT "swiftmq").

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

/* Create a text message */
RUN createTextMessage IN ptpsession (OUTPUT messageH).

RUN setText IN messageH (CMessage).

/* Publish the message on the "REQUEST" topic */
RUN sendToQueue IN ptpsession (QueueName, messageH, ?, ?, ?).   
RUN deleteMessage IN messageH.
RUN deleteSession IN ptpsession.

MESSAGE "SENT!" VIEW-AS ALERT-BOX.
RETURN "0".

My message was sent successfully!

In the documentation and in other examples, the name of the queue manager is transferred to the procedure setBrokerURL. In my case, everything works, if I pass the name of the connection factory. This is normal?

Posted by Fuelfire on 30-Mar-2017 08:19

Anand, thank you so much! Did not see your previous message.

1) In which case should I use CCDTURL for generation the .bindings file?

2) How can I generate a .bindings file for multiple queues?

 Great thanks!

Posted by Fuelfire on 30-Mar-2017 09:25

Anand, I have one more question (third): when my PASOE run Get.p my program freezes and does not respond. I think the reason is that the application server does not know how to work with "WAIT-FOR u1 OF THIS-PROCEDURE."

How to avoid an infinite loop?

[View:/cfs-file/__key/communityserver-discussions-components-files/19/Get.p:320:240]

Posted by Anand Adike on 31-Mar-2017 02:22

Hi Fuelfire,

Generally, we use .bindings file to connect WebSphereMQ remotely using JNDI approach. While creating .bindings file we need to specify the location of TAB file using CCDTURL as it contains the information about the connection factory.

We generate the .bindings file with TAB file and in the connection factory at server side we will create multiple queues to hold the messages.

Hope this helps!!

Thanks,
Anand.

Posted by Fuelfire on 31-Mar-2017 02:34

Hi, Anand! I have problems with receiving messages :-(

I modified test_get.p this way:

/*------------------------------------------------------------------------
    File        : Get.p
    Purpose     : 

    Syntax      :

    Description : 

    Author(s)   : 
    Created     : Wed Mar 22 17:06:44 MSK 2017
    Notes       :
  ----------------------------------------------------------------------*/

/* ***************************  Definitions  ************************** */

BLOCK-LEVEL ON ERROR UNDO, THROW.

/* ********************  Preprocessor Definitions  ******************** */


/* ***************************  Main Block  *************************** */
DEFINE VAR QueueManager AS CHAR NO-UNDO.
DEFINE VAR QueueName AS CHAR NO-UNDO.
DEFINE VAR CMessage AS CHAR NO-UNDO.

DEFINE VARIABLE ptpsession AS HANDLE.
DEFINE VARIABLE consumerH AS HANDLE.
DEFINE VARIABLE stillWaiting AS LOGICAL NO-UNDO INITIAL TRUE.

ASSIGN QueueManager = "RemoteCF"
                QueueName = "TEST.Q".

/* Creates a session object. */
RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H localhost -S 3620 -AppService AD.sonicMQ1 -DirectConnect").

RUN setBrokerURL      IN ptpsession (INPUT QueueManager).

/* Set user credentials. */
RUN setUser           IN ptpsession (INPUT "swiftmq").
RUN setPassword       IN ptpsession (INPUT "swiftmq").

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

/* Subscribe to the Sample.Q1 queue. Messages are handled by the "messageHandler" internal procedure. */
RUN createMessageConsumer IN ptpsession (THIS-PROCEDURE,   /* This proc will handle it */
                                         "messageHandler", /* name of internal procedure */
                                         OUTPUT consumerH).
  
/* Do not create a new message for each received message */
RUN setReuseMessage IN consumerH.

RUN receiveFromQueue IN ptpsession (QueueName,                      /* name of queue */
                                                                ?,                                      /* No message selector */
                                                                consumerH) NO-ERROR. /* Handles incoming messages*/
   
/* Start receiving messages              */
RUN startReceiveMessages IN ptpsession.

RUN waitForMessages IN ptpsession ("inWait", THIS-PROCEDURE, ?).
RUN deleteSession IN ptpsession.
/* Wait forever to receive messages since "u1" is never applied. 
WAIT-FOR u1 OF THIS-PROCEDURE.*/
MESSAGE cMessage VIEW-AS ALERT-BOX.
RETURN "0".

PROCEDURE messageHandler:
    DEFINE INPUT PARAMETER messageH AS HANDLE.
    DEFINE INPUT PARAMETER msgConsumerH AS HANDLE.
    DEFINE OUTPUT PARAMETER replyH AS HANDLE.
   
    /* Creates a reply message. The reply is published automatically when
    control returns to the ABL-JMS implementation.
    */
    ASSIGN CMessage = DYNAMIC-FUNCTION('getText':U IN messageH).
        
    RUN deleteMessage IN messageH.       
    ASSIGN stillWaiting = FALSE.    

END.

FUNCTION inWait RETURNS LOGICAL:
        RETURN stillWaiting.
END.

But when I run the program - it hangs. I do not understand where I made a mistake. Let me remind you that I want to call the program for receiving messages from the application server (PASOE).

When I interrupt execution of program I see in sonicMQ1.server.log:

S-0011>(Mar 31, 2017 10:16:29:436) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc:     Startup Parameters:
    jmsServerName: 
    Point-To-Point     
    brokerURL: RemoteCF
    user: swiftmq
    password: swiftmq
    clientID: null
    pingInterval: 
    transactedPublish: false
    transactedReceive: false
    singleMessageAck: false
    symbiontAdapter: false
    jmsDomain: true

S-0011>(Mar 31, 2017 10:16:29:436) S-0011: receive message queue size set to 10
S-0011>(Mar 31, 2017 10:16:29:437) S-0011: browse message queue size set to 500
S-0011>(Mar 31, 2017 10:16:29:437) : In SessionContainer()
S-0011>(Mar 31, 2017 10:16:29:441) : Looking up ConnectionFactory in JNDI Object Store
S-0011>(Mar 31, 2017 10:16:29:442) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: Using connection values: 26,null,true,,true,false,-1,-1,false,0,false,false,,10000,0,30,false,60,0,20,0,,swiftmq,swiftmq,depotest2,localhost
S-0011>(Mar 31, 2017 10:16:29:628) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: A JMS session has been created. (9291)
Thread-30>(Mar 31, 2017 10:16:29:636) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: receive(): Request to receive from: TEST.Q. 
Thread-31>(Mar 31, 2017 10:16:29:636) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: getNextMessage(): Client requests next message.
Thread-30>(Mar 31, 2017 10:16:29:640) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: createListener(): Message listener is set.
Thread-30>(Mar 31, 2017 10:16:29:641) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: start(): Starting message reception.
Thread-30>(Mar 31, 2017 10:16:29:642) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: start(): Message reception started.
S-0019>(Mar 31, 2017 10:30:33:797) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: stop(): Stopping message reception.
S-0019>(Mar 31, 2017 10:30:33:802) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: stop(): Message reception stopped.
S-0019>(Mar 31, 2017 10:30:33:802) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: Client was disconnected without calling deleteSession()! (9294)
Thread-31>(Mar 31, 2017 10:30:33:802) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: getNextMessage(): Sending SHUTDOWN message  to the client.
S-0019>(Mar 31, 2017 10:30:33:805) 172.25.197.193::sonicMQ1::3620::2a52856389d3b6a3:-6eb6a82c:15b23327852:-7fdc: The JMS session has been closed. (9295)

Posted by Anand Adike on 31-Mar-2017 04:28

Hi Fuelfire,

Please find the attached sample pcode to produce and consume the messages.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/8688.sample.zip:320:240]

Thank,

Anand.

Posted by Fuelfire on 31-Mar-2017 06:06

Anand, thank you. I read in the manual that I must use waitForMessages when in AppServer environment and in batch application. Well, I modified the programs.

[View:/cfs-file/__key/communityserver-discussions-components-files/19/4214.Archive.rar:320:240]

Hope it helps somebody.

In case I specify in this procedure "?" for a time interval, and there are no messages in the queue, my program starts to wait for it and stops responding. 

RUN waitForMessages IN ptpsession ("inWait", THIS-PROCEDURE, ?).

I decided to set the interval in 5 seconds to make the program complete.

RUN waitForMessages IN ptpsession ("inWait", THIS-PROCEDURE, 5).

If there are no messages in the queue, the program actually ends in 5 seconds.. But!!! I noticed such strange behavior: in the event that I put one message in the queue (and it's in the queue really one), I can get it not once but 5, 9 times. 

The message is not picked up from the queue at once. I do not understand why. If I call the procedure like this:

RUN waitForMessages IN ptpsession ("inWait", THIS-PROCEDURE, ?).

I get the message the first time..

I could stay on this variant, but then I should understand when to interrupt the execution of the program in case there are no messages in the queue.

Thanks!

Posted by Fuelfire on 31-Mar-2017 08:40

I'll correct myself. It does not matter what time interval in waitForMessages:?, 5, 10. For some reason, not the first time the last message of the queue is read. I receive the last message a few times before it is really removed from the queue. This is problem.

Posted by Fuelfire on 03-Apr-2017 03:18

Has anyone encountered such problem?

Posted by Fuelfire on 04-Apr-2017 08:04

Hello, everybody! I will try to show the the problem on example.

Here, the program for message receiving:

/* ***************************  Main Block  *************************** */
DEFINE VAR QueueManager AS CHAR NO-UNDO.
DEFINE VAR QueueName AS CHAR NO-UNDO.
DEFINE VAR CMessage AS CHAR INITIAL "" NO-UNDO.
DEFINE VARIABLE cErr AS CHAR FORMAT "X(255)" NO-UNDO.

DEFINE VARIABLE ptpsession AS HANDLE.
DEFINE VARIABLE consumerH AS HANDLE.
DEFINE VARIABLE stillWaiting AS LOGICAL NO-UNDO INITIAL TRUE.

ASSIGN QueueManager = "RemoteCF"
                QueueName = "TEST.Q".

/* Creates a session object. */
RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H localhost -S 3620 -AppService AD.sonicMQ1 -DirectConnect") NO-ERROR.
IF ERROR-STATUS:ERROR
THEN DO:
            ASSIGN cErr = ERROR-STATUS:GET-MESSAGE(1).
            RETURN "1".            
END.

RUN setBrokerURL      IN ptpsession (INPUT QueueManager) NO-ERROR.
IF ERROR-STATUS:ERROR
THEN DO:
            ASSIGN cErr = ERROR-STATUS:GET-MESSAGE(1).
            RETURN "1".            
END.

/* Set user credentials. */
RUN setUser           IN ptpsession (INPUT "swiftmq").
RUN setPassword       IN ptpsession (INPUT "swiftmq").

/* Connect to the broker. */
RUN beginSession IN ptpsession NO-ERROR.
IF ERROR-STATUS:ERROR
THEN DO:
            ASSIGN cErr = ERROR-STATUS:GET-MESSAGE(1).
            RETURN "1".            
END.

/* Subscribe to the Sample.Q1 queue. Messages are handled by the "messageHandler" internal procedure. */
RUN createMessageConsumer IN ptpsession (THIS-PROCEDURE,   /* This proc will handle it */
                                         "messageHandler", /* name of internal procedure */
                                         OUTPUT consumerH).
  
/* Do not create a new message for each received message */
RUN setReuseMessage IN consumerH.

RUN receiveFromQueue IN ptpsession (QueueName,                      /* name of queue */
                                                                ?,                                      /* No message selector */
                                                                consumerH) NO-ERROR. /* Handles incoming messages*/
IF ERROR-STATUS:ERROR
THEN DO:
            ASSIGN cErr = ERROR-STATUS:GET-MESSAGE(1).
            RETURN "1".            
END.
   
/* Start receiving messages              */
RUN startReceiveMessages IN ptpsession.

RUN waitForMessages IN ptpsession ("inWait", THIS-PROCEDURE, 5) NO-ERROR.
IF ERROR-STATUS:ERROR
THEN DO:
            ASSIGN cErr = ERROR-STATUS:GET-MESSAGE(1).
            MESSAGE cErr VIEW-AS ALERT-BOX.
            RETURN "1".            
END.

RUN deleteSession IN ptpsession.

MESSAGE cMessage VIEW-AS ALERT-BOX.
RETURN "0".

PROCEDURE messageHandler:
    DEFINE INPUT PARAMETER messageH AS HANDLE.
    DEFINE INPUT PARAMETER msgConsumerH AS HANDLE.
    DEFINE OUTPUT PARAMETER replyH AS HANDLE.
   
    /* Creates a reply message. The reply is published automatically when
    control returns to the ABL-JMS implementation.
    */
    ASSIGN CMessage = DYNAMIC-FUNCTION('getText':U IN messageH).
        
    RUN deleteMessage IN messageH.       
    ASSIGN stillWaiting = FALSE.    

END.

FUNCTION inWait RETURNS LOGICAL:
        RETURN stillWaiting.
END.

When I run this program, I get the last message in the queue several times. If I delete string 

RUN deleteSession IN ptpsession.

I get the last message once (and it's correct). But there is a line
Client was disconnected without calling deleteSession()! (9294)
in the soniqMQ1.server.log.
That is, if I do not delete the session, the program works correctly. This is normal?

Posted by Fuelfire on 14-Apr-2017 08:06

Hello, everybody! I did several tests and now the problem is more or less clear. In the event that messages are received through the application server (I use PASOE), there is a problem when the message is received, but it remains in the queue. So I get some messages several times. If you receive messages directly from the client, then everything is OK!

In accordance with the regulations, I must communicate with the WebSphere MQ in the "server-server" scheme. Therefore, a working solution: connecting to the Sonic adapter directly from the client is not acceptable. Has anyone encountered a similar problem?

This thread is closed