I now need to try this on a Red Hat Linux system, but I am having some
problems with linking, so would much appreciate some help. I am using
the simple "Hello World" example given on SUN's website with version
1.4 of the SDK. I can compile "HelloWorld.java" OK, and I can
generate the "h" file required for the C file HelloWorldImp.c, but
this is where I am having problems. The command
gcc -fPIC -shared -o hello.so HelloWorldImp.c
compiles OK and generates the shared library hello.so, but when I
attempt to run the java program using the command java HelloWorld, I
get the following error messages:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in
java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)
at HelloWorld.<clinit>(HelloWorld.java:5)
where line 5 corresponds to the statement
"System.loadLibrary("hello");".
I checked SUN's website and there is a comment about setting the
environment variable LD_LIBRARY_PATH to the path where the file
"hello.so" is located using the command "setenv LD_LIBRARY_PATH
/home/csharp/java/", but this does not appear to work.
Could someone kindly explain what I am doing wrong - many thanks.
Christopher Sharp
Are you sure the rest of your classes are set up correctly?
I suspect it can't find java.lang.String
Alun Harford
I don't think so... the exception said clearly "UnsatisfiedLinkError: no
hello in java.library.path" from the "loadLibrary()" call.
It seems to me that the OP is setting the path correctly.
I searched on Google using the term "loadLibrary UnsatisfiedLinkError Linux"
and found an interesting post (sorry for word-wrapped link):
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=392D7DAA
.39A662CA%40cryptocard.com&rnum=2&prev=/groups%3Fq%3DloadLibrary%2BUnsatisfi
edLinkError%2BLinux%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D392
D7DAA.39A662CA%2540cryptocard.com%26rnum%3D2
The fourth post said an UnsatisfiedLinkError can be triggered when the
native code is not compiled correctly (some static libraries were not
linked).
May be you're hitting the same problem?
HTH,
KC
Add -D_REENTRANT to the compile flags.
> compiles OK and generates the shared library hello.so, but when I
> attempt to run the java program using the command java HelloWorld, I
> get the following error messages:
>
> Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello
> in java.library.path
System.loadLibrary("hello") attempts to load libhello.so, so rename
the library. This is your main problem.
The library must be somewhere in the system library path (see
documentation for ldconfig, also look in /etc/ld.so.conf for list of
standard places plus /lib and /usr/lib). If that isn't the case, you
can define your own LD_LIBRARY_PATH to include the directory where the
library is.
> "setenv LD_LIBRARY_PATH /home/csharp/java/", but this does not
> appear to work.
In csh, tcsh and related shells, use setenv like above.
In sh, bash, ksh and similar, use this syntax instead:
LD_LIBRARY_PATH=/home/csharp/java (no spaces around "=")
export LD_LIBRARY_PATH
You can also do this:
LD_LIBRARY_PATH=somepath java Hello
/gordon
--
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Hi Gordon,
Thanks for the advice from last week, but I'm still having problems.
I would have got back to you sooner, were it not for the fact that
last week I was very busy, and had an exam in Java, although not in
JNI.
I have Linux RedHat version 8.0 and JDK 1.4, and as was stated on
March 8, I created a simple HelloWorld.java file taken from Sun's
website. It is:
class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
I then used javah to create the header file HelloWorld.h. After this
I created the file HelloWorldImp.c
#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) {
printf("Hello world!\n");
return;
}
which I compiled and linked using
gcc -o hellolib.so -D_REENTRANT -shared -Wl,-soname,hello.so \
-I/home/csharp/java/j2sdk1.4.2_03/include \
-I/home/csharp/java/j2sdk1.4.2_03/include/linux \
HelloWorldImp.c -static -lc
where the path to my Java and C files is /home/csharp/java, and the
path to Java is /home/csharp/java/j2sdk1.4.2_03. This created the
library file hellolib.so.
I then set the path to my working directory by typing:
set LD_LIBRARY_PATH=/home/csharp/java
then attempted to run the program using java HelloWord, but I always
get the error messages:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in
java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)
at HelloWorld.<clinit>(HelloWorld.java:5)
I followed your advice my renaming hellolib.so to hello.so, and tried
other various changes, but I always get the same errors. It seems
that no matter what I do, I am unable to get Java to pick up the file
hellolib.so, or whatever name I give it. Could you or someone else
kindly help get this problem resolved - many thanks.
Christopher Sharp
That wasn't my advice. The right name is libhello.so, not hellolib.so
or hello.so.
> gcc -o hellolib.so -D_REENTRANT -shared -Wl,-soname,hello.so \
> -I/home/csharp/java/j2sdk1.4.2_03/include \
> -I/home/csharp/java/j2sdk1.4.2_03/include/linux \
> HelloWorldImp.c -static -lc
Use this command line instead:
gcc -D_REENTRANT -fPIC -shared \
-I/home/csharp/java/j2sdk1.4.2_03/include \
-I/home/csharp/java/j2sdk1.4.2_03/include/linux \
HelloWorldImp.c -o libhello.so
Or these two:
gcc -D_REENTRANT -fPIC
-I/home/csharp/java/j2sdk1.4.2_03/include \
-I/home/csharp/java/j2sdk1.4.2_03/include/linux \
-c HelloWorldImp.c
gcc -shared HelloWorldImp.o -o libhello.so
Confirm that you've correctly built a shared object:
file libhello.so
> set LD_LIBRARY_PATH=/home/csharp/java
That wasn't my advice either.
If you are using tcsh or csh, use setenv (not set) to set
LD_LIBRARY_PATH:
setenv LD_LIBRARY_PATH /home/csharp/java
If you are using bash, ksh or similar, use these two lines:
LD_LIBRARY_PATH=/home/csharp/java
export LD_LIBRARY_PATH
Or put the library in /lib, /usr/lib, or one of the directories
mentioned in /etc/ld.so.conf.
It works - many thanks! Sorry for mis-reading your advice. I was
under a lot of pressure last week.
Presumably I can now move on and get some real Java and C code on
Windows 2000 to work on Linux.
Christopher Sharp