views:

49

answers:

3

I am trying to build and run an example jni program. The program is just a sample helloworld program. I did not write it but I assume that it works. I am running this on Linux. There are four files.

HelloNative.c  
HelloNative.h  
HelloNative.java  
HelloNativeTest.java  

To build the files, I did

gcc -I/myDir/jdk/include -I/myDir/jdk/include/linux -fPIC -c HelloNative.c  
gcc -shared -o HelloNative.so HelloNative.o  
java *java

Here is the result of the build

HelloNative.c  
HelloNative.h  
     HelloNative.o  
   HelloNativeTest.class  
HelloNative.class  
HelloNative.java  
HelloNative.so  
HelloNativeTest.java

Then I did

setenv LD_LIBRARY_PATH /myDir/myExample:${LD_LIBRARY_PATH}  
java HelloNativeTest

I got the following error

Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path  
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)  
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)  
        at java.lang.System.loadLibrary(System.java:1028)  
        at HelloNative.<clinit>(HelloNative.java:9)  
        at HelloNativeTest.main(HelloNativeTest.java:8)  

I checked the LD_LIBRARY_PATH and the HelloClassTest and HelloNative.so, they were all there. I tried to specify the -CLASSPATH also, but that did not seem to matter. Does anyone have any ideas ?

A: 

You can also try by setting the java.library.path:

java -Djava.library.path=/myDir/myExample HelloNativeTest
dogbane
That option did not make any difference.
tadpole
A: 

Did you do a System.loadLibrary() from Java?

Jonathan
Like I said this is straight from Sun Java tutorial package. I assume they know what they are doing. I did check and they did have class HelloNative { public static native void greeting(); static { System.loadLibrary("HelloNative"); } }
tadpole
Libraries on Linux are expected to begin with "lib". Try renaming to libHelloNative.so?
Jonathan
A: 

Do the following, where X="HelloNative".

  • Give the library a filename following a system-dependent standard. On Linux, name your library libX.so.
  • Set the java.library.path System property to the directory containing your library.
  • Call System.loadLibrary("X") where "X" is the cross-platform part of the library name above.

You named your library HelloNative.so; change it to libHelloNative.so.

From http://download.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp679:

The argument to System.loadLibrary is a library name chosen arbitrarily by the programmer. The system follows a standard, but platform-specific, approach to convert the library name to a native library name. For example, a Solaris system converts the name pkg_Cls to libpkg_Cls.so, while a Win32 system converts the same pkg_Cls name to pkg_Cls.dll.

If you use OSGi in the future, there's an alternative to setting java.library.path.

Andy Thomas-Cramer
Yes, thank you Andy. Changing the HelloNative.so to libHelloNative.so did the trick.
tadpole
@tadpole - Happy to hear that. You can also show your appreciation by "accepting" this answer via clicking the checkbox to the left of this answer. Your rate of accepting answers will impact the number of answers you get on future questions. More details are at http://stackoverflow.com/faq .
Andy Thomas-Cramer