• Post Reply Bookmark Topic Watch Topic
  • New Topic

JNI - javah on classes that don't belong to the default package  RSS feed

 
Spencer J Lee
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,
I've been wetting my feet using JNI and have successfully run the simplest of examples. But I seem to get stuck when I try creating a slightly different Java class.
Basically, I've created a class called com.test.TryJNI.
From the current directory, it's source is
./com/test/TryJNI.java
I'm compiled it, and its class file is.
./com/test/TryJNI.class
TryJNI contains
- a single native method
- the static initializaiont to load the appropriate library
- a main to call the native method.
Now, here's where I'm confused...
when I run javah, do i run...
- javah -jni -classpath com.test.TryJNI
OR
- javah -jni com/test/TryJNI
The first creates the header file "com_test_TryJNI.h"
The second creates the header file "com_0002ftest_0002fBBoxFuncs.h"
Regardless, I've tried both...
After creating the header file, created the .cc file to include the proper header file, complied the cc file, and created a dynamic library with the resuling o file.
The executable script the runs the main in the TryJNI file correctly sets the classpath and the LD_LIBRARY_PATH.
But I still get...
Exception in thread "main" java.lang.UnsatisfiedLinkError: <native method>
<stack trace>

Now if I don't put TestJNI in a package by opting to exclude the package line at the top file source, everything works...
(i.e. I simply run javah -jni TryJNI in that case.)
Anyone have any ideas? I'm trying to figure out the best way to organize JNI code.
Thanks for all help!
 
Mathews P Srampikal
Ranch Hand
Posts: 211
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
in windows if u have a TryJNI class then
javah -jni TryJNI will create the .h file
Now you go to c file and include jni.h and the created .file and create the DLL.
Now set the path to that created DLL . Note that the created DLL and lodliobrary("blah.dll") shold be same.
Then run the java class.u will get the result.
 
Spencer J Lee
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I didn't mention this earlier, but basically I'm trying to call native methods from within a Java application.
I'm actually attempting this on a Solaris machine, but lets say I did have a Windows machine...
How would I create the header class using javah if my class was com.test.TryJNI instead of just TryJNI.
I could imagine it could be one of the following if from the currenct directory, the location of the class and java file were ./com/test/TryJNI.class and ./com/test/TryJNI.java
1) javah -jni com/test/TryJNI # The path of the class
2) javah -jni -classpath com/test TryJNI
3) javah -jni -classpath . com.test.TryJNI
My guess is it would be the third.
Does this question make sense?
Thanks
 
Spencer J Lee
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, look what I found on the bottom of the javah -h printout...

Usage: javah [options] <classes>
where [options] include:
-help Print this help message
-classpath <path> Path from which to load classes
-bootclasspath <path> Path from which to load bootstrap classes
-d <dir> Output directory
-o <file> Output file (only one of -d or -o may be used)
-jni Generate JNI-style header file (default)
-old Generate old JDK1.0-style header file
-stubs Generate a stubs file
-version Print version information
-verbose Enable verbose output
-force Always write output files
<classes> are specified with their fully qualified names (for
instance, java.lang.Object).
 
Spencer J Lee
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And, I just found a solution to my problem. I'm posting it here just in case anyone else was or will be interested...
Recap of the problem:
My JNI program works fine until I place the java code into a package. When I do this and run my code I get the java.lang.UnsatisfiedLinkError.
Solution: (by gordon, found on comp.lang.java.help)
When you move the class into a package, the names of the native
methods must be changed to reflect that.
Simply re-run javah *after* putting the class in a package and use
those names instead of the current ones.
This problem can be (almost) avoided if you have a static native init
method that calls RegisterNatives to register the remaining methods.
Only the init method needs to follow the naming convention and the
others can be named any way you like.
/gordon
Hope this is helpful to others too.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!