Author |
Message
|
elvis_gn |
Posted: Wed Jan 05, 2011 5:29 am Post subject: JavaCompute to JNI to Windows dll call |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi all,
Has anyone implemented a JavaCompute code which calls another class, which inturn loads a dll library and does static native calls to the dll methods ?
Any sample would be highly appreciated.
Regards. |
|
Back to top |
|
 |
lancelotlinc |
Posted: Wed Jan 05, 2011 6:30 am Post subject: |
|
|
 Jedi Knight
Joined: 22 Mar 2010 Posts: 4941 Location: Bloomington, IL USA
|
I have used System.loadLibrary("C:/some.dll"); On Unix, you can also do same: System.loadLibrary("/somedir/some.so");
You can also specifiy on JVM command line, args to load the DLL at JVM runtime.
This is fairly common knowledge, did it not work for you? _________________ http://leanpub.com/IIB_Tips_and_Tricks
Save $20: Coupon Code: MQSERIES_READER |
|
Back to top |
|
 |
elvis_gn |
Posted: Thu Jan 06, 2011 7:29 am Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi lancelotlinc,
I have got the System.load to work, but the situation I think, is a little more complex.
I received an existing Eclipse java project where a parent class A invokes a class B. The class B contains the System.load and static native jni calls. The C header file and dll is specific to the class B hence I'm trying to reuse the class B as such in the broker.
Now from Broker, I have a JavaCompute node in the flow. From the usual JavaCompute wizard, I created a Java project and pasted the class B, dlls and C header into the exact same packages as the above.
The evaluate of the JavaCompute is invoking the class B object creation and further calling the methods of class B in a static manner.
The challenge currently is that, the code for any first method call is making the flow hang...control does not return to broker, no exception is thrown and heap seems to be increasing...increased the heapsize but no difference.
Now my first doubt is if this is even the correct way, or should I be pasting everything from class B into the java compute class...but in that case I need to create the C header for my javaCompute class.
What was your approach ?
Regards. |
|
Back to top |
|
 |
lancelotlinc |
Posted: Thu Jan 06, 2011 7:46 am Post subject: |
|
|
 Jedi Knight
Joined: 22 Mar 2010 Posts: 4941 Location: Bloomington, IL USA
|
I assume that this DLL has some unique possibly vendor-specific code that cannot easily be replicated. This holding true would eliminate the best approach which would be to recode in Java.
Under the assumption that we cannot recode, I would start in a fresh and clean, newly created POJO (Plain Old Java Object). You can do this from Broker toolkit, if you select the Other -> Java perspective.
I would create a new POJO and make the POJO work flawlessly with several regression test cases. Notice we are not using any JCN code, just simply some Java code in a standalone Java project.
To run this Java POJO, choose File -> Export -> Export as JAR. Then from a command line, start a JVM the normal way, passing the JAR in on the classpath and telling the JVM where the main() function resides. Once you get this to work successfully repeatedly in an autmated test case fashion, all you need to do is from a JCN is call your JAR like any other JAR.
Make sense? I'm glad to help you if you get stuck. Please ask more questions.
Lance _________________ http://leanpub.com/IIB_Tips_and_Tricks
Save $20: Coupon Code: MQSERIES_READER |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Jan 06, 2011 8:03 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
I don't think that creating another standalone program will assist in debugging this in Broker runtime.
I would start in the same manner that elvis_gn has done, by creating a JCN class that calls out to the existing Java code that calls the DLL.
The difficulty then comes in in making sure that all of the necessary pieces are available at runtime. You will need to ensure that the loadLibrary call uses a full path to the DLL and that the Broker service ID has permissions to that DLL and that the full path is visible to the Broker service ID (either a local file system or a system wide drive mount, rather than a user level drive mount).
Then I'd deploy the flow, and do a full restart of the Broker. Then I'd test it, and if it didn't work, I'd run a service trace to see where it's failing. |
|
Back to top |
|
 |
lancelotlinc |
Posted: Thu Jan 06, 2011 8:17 am Post subject: |
|
|
 Jedi Knight
Joined: 22 Mar 2010 Posts: 4941 Location: Bloomington, IL USA
|
What you prove when starting fresh in a POJO is that the Java connection to the DLL works isolated from the Broker runtime. When you integrate the POJO jar into Broker runtime, you then should work with no changes whatsoever.
You can do it any way you want. But simplifying the complex to create an elegant solution is the more mentally healthier way to do it IMHO. I've already spent too much money fixing drywall from my head banging days. Would rather not get any more bruises on my head. _________________ http://leanpub.com/IIB_Tips_and_Tricks
Save $20: Coupon Code: MQSERIES_READER |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Jan 06, 2011 9:15 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
lancelotlinc wrote: |
What you prove when starting fresh in a POJO is that the Java connection to the DLL works isolated from the Broker runtime. |
The eclipse project has apparently already proven that. I'd lay even money that it's already doing a standalone Java execution. |
|
Back to top |
|
 |
lancelotlinc |
Posted: Thu Jan 06, 2011 9:41 am Post subject: |
|
|
 Jedi Knight
Joined: 22 Mar 2010 Posts: 4941 Location: Bloomington, IL USA
|
Its a little different, in that elvis is trying to use classes inside the JCN and I am advocating the creation of a standalone JAR file that is called from the JCN. _________________ http://leanpub.com/IIB_Tips_and_Tricks
Save $20: Coupon Code: MQSERIES_READER |
|
Back to top |
|
 |
elvis_gn |
Posted: Fri Jan 07, 2011 9:10 am Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi guys,
Thanks for the inputs.
I put a main to the JNI invoking class and find that it runs smoothly.
I then did both the deployment along with the JCN project and deployment via shared-classes (separate jar for the jni class and dlls).
Both work the same, in the sense that the flow is hung in the JCN node. From the debug I know that the jni class object creation (loading the library) goes through, but any next jni method call gets hung.
Not sure if you guys want to get your hands dirty, but the Eclipse Java project is available here. The jni class and dlls are all within the project. NIST_Demo will be the class you need to invoke from JCN.
Regards. |
|
Back to top |
|
 |
lancelotlinc |
Posted: Fri Jan 07, 2011 9:40 am Post subject: |
|
|
 Jedi Knight
Joined: 22 Mar 2010 Posts: 4941 Location: Bloomington, IL USA
|
Hi elvis, I would love to tinker with the source but dont have time to be thorough. mqjeff may have a different approach, but here is what i would do.
Using only your standalone jar, not in Broker, just on the command line, tinker with it till it works. I suspect some intialization is not happening in the DLL. Look for some public functions in the DLL that lead you to believe they have to do with initialization.
Also, DLLs sometimes pass back some block of memory that you must use on subsequent calls. If you don't preserve that CDATA just right, the DLL may be confused on your second calls.
In short, make it work in a standard Java environment, then integrate your working JAR to Broker after you know that it works. What we learned is, your current code is the culprit, not the Broker runtime.
Please keep posting new info as you find it out.
Lance _________________ http://leanpub.com/IIB_Tips_and_Tricks
Save $20: Coupon Code: MQSERIES_READER |
|
Back to top |
|
 |
elvis_gn |
Posted: Sun Jan 09, 2011 8:54 am Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi guys,
Ran out of time to submit the proposal, so had to drop the entire attempt...for now
I got the dlls working with standalone java code in every way possible, it just didn't work from inside the broker.
I realised a few things though:
1. the dlls either have to be loaded through environment variables or with the JCN, putting the dlls in a jar with jni did not load them...even though its the jni class which actually called the load...which means it was a classloader difference.
2. the dlls could not be loaded with System.LoadLibrary("dll name without .dll extension), irrespective of where I placed it (for env variables, you don't require to load). I had to use System.load(full path) always.
lancelotlinc: as you mentioned, the dlls were supposed to pass a block of memory which updated the jni class object initialized from the JCN, this is what was not happening successfully. Unfortunately, what was returned by the method was an integer status of 1/0 and not CDATA, the object was being updated differently, which I cannot interpret without the source code.
In the end the broker got hung all the time without any error, nothing much I could do.
In case someone has done a dll implementation, please put up a developerWorks article
Regards. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sun Jan 09, 2011 10:53 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Did you change the security policy to allow for a successful call of SecurityManager.checkLink(your_dll_loc)?
Code: |
from the SecurityManager class API:
public void checkLink(String lib)
Throws a SecurityException if the calling thread is not allowed to dynamic link the library code specified by the string argument file. The argument is either a simple library name or a complete filename.
This method is invoked for the current security manager by methods load and loadLibrary of class Runtime.
This method calls checkPermission with the RuntimePermission("loadLibrary."+lib) permission.
If you override this method, then you should make a call to super.checkLink at the point the overridden method would normally throw an exception.
Parameters:
lib - the name of the library.
Throws:
SecurityException - if the calling thread does not have permission to dynamically link the library.
NullPointerException - if the lib argument is null.
See Also:
Runtime.load(java.lang.String), Runtime.loadLibrary(java.lang.String), checkPermission
|
_________________ MQ & Broker admin |
|
Back to top |
|
 |
elvis_gn |
Posted: Tue Jan 11, 2011 5:28 am Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi all,
Confirmed with labs that dll to broker JVM updation is not allowed...the dll method should respond back information via method return types.
Regards. |
|
Back to top |
|
 |
|