Author |
Message
|
bobbee |
Posted: Thu Mar 12, 2015 8:02 am Post subject: loadlibrary location |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
I am calling the following C program from JAVA called from ESQL. It performs a load of the program from 'System.loadLibrary' Where is that on Windows and eventually AIX. I would assume this relates to the Broker (IIB) runtime. My laptop is Windows 7 running IIB v9.0.0.2. AIX will be the same version of IIB.
Code: |
public class HelloWorld {
/* native void helloFromC(); */
/* static { */
/* System.loadLibrary("ctest"); */
/* } */
public static String compress() {
/* HelloWorld helloWorld = new HelloWorld(); */
/* helloWorld.helloFromC(); */
return "1";
}
} |
|
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Mar 12, 2015 8:25 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
I would assume for windows, that the only requirement is that the .dll is on the path... or on the java.library.path like in JVM arg -Djava.library.path="c:\xyz;c:\stvw;." Note that there is a specific java to native interface that you c program will have to implement... and it gets generated off the java class using the native call...
Seems a little bit complicated... why no directly write a custom node in C?  _________________ MQ & Broker admin |
|
Back to top |
|
 |
bobbee |
Posted: Thu Mar 12, 2015 8:32 am Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
I did all the footwork for the build. when i comment out the System.Loadlibrary('ctest') code it works. Otherwise i get a class def not found. So the load is mucking up. I download CodeBlock and I am issuing this command and it creates ctest.dll.
gcc -o ctest.dll -shared -I C:\IBM\IntegrationToolkit90\jdk\include ctest.c -lc |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Mar 12, 2015 8:43 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Does it work if you load the library in a standalone java program?
Have you tried System.load(absolute path), or System.loadLibrary("xyz.dll")
This would narrow down the problem...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
bobbee |
Posted: Thu Mar 12, 2015 11:40 am Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
I added the location to the PATH, I also tried the following. Still does not work which causes a Class Def not found
System.load("C:\\ProgramData\\IBM\\MQSI\\config\\IB9NODE\\default\\shared-classes\\ctest");
System.loadLibrary("ctest.dll");
System.loadLibrary("ctest");
I also added the path to the DLL in mqsiprofile to MQSI_LILPATH |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Mar 12, 2015 12:48 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
missing the .dll in the System.load() call.
What happened to ctest.h (generated by the java compiler?)  _________________ MQ & Broker admin |
|
Back to top |
|
 |
bobbee |
Posted: Thu Mar 12, 2015 1:02 pm Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
The instructions said to copy the function definition into the C program. i did this Here is the C code I compiled
/* ctest.c */
#include <jni.h>
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
(JNIEnv * env, jobject jobj)
{
printf("Hello from C!\n");
} |
|
Back to top |
|
 |
bobbee |
Posted: Thu Mar 12, 2015 1:49 pm Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
This was the full file. I ran it against the java file in the Toolkit
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_cbs_common_HelloWorld */
#ifndef _Included_com_cbs_common_HelloWorld
#define _Included_com_cbs_common_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_cbs_common_HelloWorld
* Method: helloFromC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_cbs_common_HelloWorld_helloFromC
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Mar 12, 2015 6:29 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
bobbee wrote: |
This was the full file. I ran it against the java file in the Toolkit
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_cbs_common_HelloWorld */
#ifndef _Included_com_cbs_common_HelloWorld
#define _Included_com_cbs_common_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_cbs_common_HelloWorld
* Method: helloFromC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_cbs_common_HelloWorld_helloFromC
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif |
Looks about right for the JNI interface call  _________________ MQ & Broker admin |
|
Back to top |
|
 |
bobbee |
Posted: Fri Mar 13, 2015 2:21 am Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
I will add the suffix to the program name on the System.Load.
I added -Djava.library.path="c:\IIBShared;." to the JVM System Properties in the EG in the Integration Explorer and rebooted IIB. I now have a new IIB server. I could not get to the server either through the Integration Explorer of from the command line to reset that. i had to delete the default configuration and se it back up. maybe it was the ';.' that did it. I cannot see adding on library doing that unless that reset the entire java.Library.path to just that. Would have thought 'append' would be the end result. But.... |
|
Back to top |
|
 |
kimbert |
Posted: Fri Mar 13, 2015 3:18 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
I'm now wondering what problem you are solving, if the best solution is ESQL calling Java calling C via JNI... _________________ Before you criticize someone, walk a mile in their shoes. That way you're a mile away, and you have their shoes too. |
|
Back to top |
|
 |
bobbee |
Posted: Fri Mar 13, 2015 3:45 am Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
C program takes an iDoc, originally coming from R3, yes R3, they have this supporting one of the biggest systems internally and are just moving to the up-to-date integration methods, but I digress.
The C program takes the iDoc and compresses it into a proprietary format. He finds the last character in each segment, looses the spaces and the adds alot of control characters to the segment in the new compressed format and then puts a length descriptor on the front, slides all the segments together and then writes that message to MQ, out to the partner(s). I see in one of the docs this was to bypass the 104 meg restriction on MQ. I am having my doubts but this is the way the partner is configured and they will not change.
I thought it would be rather EASY to just pass the C program the iDOC, let him do his acceptable work, pass the compress buffer back to me and I send it.
Great idea on paper. This seemed like a simple thing. Sort of an normal use case. Man on the moon, but we cannot call a C program easily.
BTW, there are about 6 of these exits do all kind of things. So it is not one. If I got this working I would have used it as a template for the others. |
|
Back to top |
|
 |
fjb_saper |
Posted: Fri Mar 13, 2015 4:48 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Typically for this to work you need:
- a java JNI call with the parameters
- a C library that has the JNI interface and calls correctly into the existing C library (Which in all likelihood did not have any JNI calls pre-configured.
- both C libraries, either on the path or on the java.library.path (windows), On the LIBPATH, or LD_LIBRARY_PATH or some such in Unix/Linux
Test it from a java stand alone.
See how it works, incorporate into IIB.
And think all the time about thread safety... and whether you need synchronization... and scalability... _________________ MQ & Broker admin |
|
Back to top |
|
 |
bobbee |
Posted: Fri Mar 13, 2015 6:33 am Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
So, I followed the instructions at this link. I used his C program example to just get a test up.
http://stuf.ro/calling-c-code-from-java-using-jni
I used the JAVA routine I had in a JAVA project in IIB and generated the .h file from the JAVA code. I took out what I needed and put it in the C program.
I got the FLOW to call the JAVA (this I have done before with Caching). When In the Compute node when I comment out the System.loadlibrary code it works. When it is in it sez Class not found. I was told if the LOAD is not working that is the response I will get back from the whole class call. I tried some suggestions, I do think I messed one up from the comment made. I have to go back and correct that. I did not fully qualify the System.Load target. I will get this working if it kills me. I think my problem is it does not see the library and cannot pick up the module to load. |
|
Back to top |
|
 |
bobbee |
Posted: Fri Mar 13, 2015 6:35 am Post subject: |
|
|
 Knight
Joined: 20 Sep 2001 Posts: 545 Location: Tampa
|
you made a statement that has me questioning what I am doing. I have a single C program named ctext. yet you say this:
a C library that has the JNI interface and calls correctly into the existing C library (Which in all likelihood did not have any JNI calls pre-configured.
So it seems you are saying two C programs. I don't get this from the instructions. |
|
Back to top |
|
 |
|