-
1. Re: unsatisfiedLinkError generated when trying to access JNI
dannyyates Jun 24, 2004 9:53 AM (in response to jikramer)What you are trying to do is disallowed by the J2EE spec. Having said that, JBoss does nothing specific to prevent you from using JNI.
Have you managed to make this work outside the JBoss environment? i.e. write a simple standalone Java program and try it. Note that the method name mangling used by JNI needs to be adhered to, and the method exported from the DLL. -
2. Re: unsatisfiedLinkError generated when trying to access JNI
jikramer Jun 24, 2004 11:21 AM (in response to jikramer)Thanks for your post.
Yes, calling this .dll works fine outside jboss. I have also looked inside the .dll to match up the method name i'm calling. it is "aaBond_crv1_java", and I have found "aaBond_crv1" in the .dll. I have tried both with success in my test program, but both give me the same unsatisfiedLinkError(nativeMethod) when I build & deploy my .jar.
Actually I also tried the javah -jni className which generated the following method name:
JNIEXPORT jdoubleArray JNICALL Java_ShowBondcrv1_aaBond_1crv1_1java
(JNIEnv *, jobject, jdouble, jobjectArray, jobjectArray, jobjectArray, jint, jint, jint, jobjectArray, jint);
Interestingly this did not work in the standalone.
Any ideas?
Thanks! -
3. Re: unsatisfiedLinkError generated when trying to access JNI
dannyyates Jun 24, 2004 11:30 AM (in response to jikramer)Are you sure this is right? This would imply a method called 1java in a class called 1crv1 in a package called ShowBondcrv1.aaBond. Neither the package name nor the class name follow normal Java naming conventions, and the method name is simply illegal.
If your method name has _ characters in it, firstly consider renaming your method in accordance with traditional Java coding conventions. Secondly, you'll have to look at the JNI spec for how to encode those method names in C because the _ character has a special meaning in the C signature.
The hashCode() method in java.lang.Object is native. It would require a C++ method with signature Java_java_lang_Object_hashCode(...)
Also, note that if your DLL is written in C++, you'll need an extern "C" directive:
extern "C" JNIEXPORT void JNICALL Java_java_lang_Object_hashCode(JNIEnv* env, jobject self) -
4. Re: unsatisfiedLinkError generated when trying to access JNI
jikramer Jun 24, 2004 11:46 AM (in response to jikramer)All I can say about this generated method name is that it does not work in the sample or in jboss. I'm getting this .dll & sample calling program from a 3rd party, but it does run fine standalone.
So my bigger question here is more about insuring the .dll(s) are getting loaded property when i'm running jboss. Is there more to it then dumping necessary .dll's in the JBOSS bin and then pointing to them with System.load?
Thanks -
5. Re: unsatisfiedLinkError generated when trying to access JNI
dannyyates Jun 24, 2004 11:54 AM (in response to jikramer)If System.LoadLibrary returns without an exception, the library loaded OK (I think).
I can't conceive of any legal Java method signature which the JVM would map to the C method signature you've quoted.
Tell me the full package name, class name and method name of the Java native method, and I'll tell you what the C method should look like. -
6. Re: unsatisfiedLinkError generated when trying to access JNI
jikramer Jun 24, 2004 11:59 AM (in response to jikramer)This sample app works, but the same thing does not work in jboss.
here's the method name:
/* Prototype for Java Native Interface wrapper function from CJavaWrap.dll */
public native double[] aaBond_crv1_java(double d_v, double[][] cash_crv, double[][] fut_crv, double[][] bond_crv, int method_boot, int rate_basis, int acc_rate, double[][] hl,
int method_gen);
No package name in the sample program
and the class name: ShowBondcrv1.java.
As I mentioned earlier, looking inside the .dll, there exists a method aaBond_crv1.
Thanks -
7. Re: unsatisfiedLinkError generated when trying to access JNI
dannyyates Jun 24, 2004 12:46 PM (in response to jikramer)I guess that would map to a C method called Java_ShowBondcrv1_aaBond_crv1_java, except that I'm not sure how the _ characters in the method name are handled. Looking at your earlier example, it might turn _ into _1, which would leave the C method as Java_ShowBondcrv1_aaBond_1crv1_1java, which is exactly what you said!
However, given that your DLL isn't exporting this method, I'm a bit stuck how it's working.
Is your simple app a Java app? Or is it a C app which uses JNI to go out to the Java and back to the C? It is possible (from the C side) to tell the JVM to override its normal mapping of Java names to C names.
So if your simple app is working, I suspect it is working in one of two ways:
1) It is a C application (.exe) which loads a JVM through the JNI Invokation API, and then explicitly tells the JVM to use the C aaBond_crv1 method when it encounters the particular Java native method, or
2) It's a Java application that first makes a call to a native initialisation method in the DLL which sets up the same mapping from Java method to C method which I've described above.
The JVM maps Java method names to C method names using the algorithm I've already described, or by being told explicitly what the mapping is for a given Java method. But this explicit mapping can only happen from C code (using a method called JNI_RegisterNatives, or something similar).
Anyway, this is really outside the scope of JBoss.
Things to try:
1) Is the sample app a native exe? If so, you might be stuck.
2) Is there a native init method that needs to be called?
3) Are you sure you're looking at the right DLL?
4) Are you sure JBoss is loading it? Try removing it and seeing if you get an exception. Try replacing it with a corrupt file (e.g. type a few words into Notepad, and save the file with a .DLL extension). This will prove that it's finding the file and trying to load it.
5) Are you sure you're calling System.loadLibrary before you're calling the native method? -
8. Re: unsatisfiedLinkError generated when trying to access JNI
jikramer Jun 24, 2004 2:05 PM (in response to jikramer)The sample app is a java app.
Thanks for your ideas - here's where I stand:
1) Is the sample app a native exe? If so, you might be stuck.
--> Sample app is a java app.
2) Is there a native init method that needs to be called?
--> native init? unsure what you mean here.. when I call the method in the sample app, it works. When I call it from my app in jboss, no workie.
3) Are you sure you're looking at the right DLL?
--> yes
4) Are you sure JBoss is loading it? Try removing it and seeing if you get an exception. Try replacing it with a corrupt file (e.g. type a few words into Notepad, and save the file with a .DLL extension). This will prove that it's finding the file and trying to load it.
--> yes. without this .dll, it gives me an unsatisfiedLinkError(CWrapJava.dll). When I include the .dll in the jboss/bin directory & point to it through System.load, it loads it fine but fails when I call the method.
5) Are you sure you're calling System.loadLibrary before you're calling the native method?
Yes. I've tried this in a static method which got called when the object was loaded (constructed ), and also put it in the constructor. -
9. Re: unsatisfiedLinkError generated when trying to access JNI
jikramer Jun 30, 2004 9:14 AM (in response to jikramer)this should not be so hard.. is it not possible through JBOSS? I have seen posts elsewhere that possibly the library is getting loaded > 1 time?! any way to verify or protect against this?
thanks -
10. Re: unsatisfiedLinkError generated when trying to access JNI
jikramer Jul 6, 2004 10:42 AM (in response to jikramer)SOLUTION:
The java project we were working on was in a package. The .dll header needs to contain a package name for the JNI process to bind to it, so it needed to be recompiled with package name embedded in the method. -
11. Re: unsatisfiedLinkError generated when trying to access JNI
dannyyates Jul 7, 2004 4:21 AM (in response to jikramer)Hmm... see when I talked about JNI method name mangling, and package names (repeatedly?) And you also told me that your code wasn't in a package!
Oh well. Glad you got it sorted.