Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with JNI on Linux

1 view
Skip to first unread message

Howard

unread,
Jan 24, 2007, 2:18:12 PM1/24/07
to
I am having a problem getting JNI to work on Linux. I think it is with
how I am creating the shared object file. I am using Java 1.5.0_8 and
Redhat Enterprise version 3 release 4. I have not used JNI before so I
did a web search and found a simple example that I am trying to get to
work. The problem is that I am getting an UnsatisfiedLinkError. It looks
like there are many flavors of this error and I can get at least three
of them :(

My Java program is:


class FirstJNI
{
public native void displayHelloWorld();
public native void displayOther();
public native String getLine(String prompt);

static {
System.out.println("in static");
System.loadLibrary("FirstJNI");
}

public static void main(String[] args)
{
System.out.println("entered main");
System.out.println("creating new FirstJNI");
FirstJNI jN=new FirstJNI();
jN.displayHelloWorld();
jN.displayOther();

String input = jN.getLine("Enter Some Thing ");
System.out.println("You Entered " + input);
}
}

and my c library is:

#include "FirstJNI.h"
#include <stdio.h>

JNIEXPORT void JNICALL
Java_FirstJNI_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world! \n");
return;
}

JNIEXPORT void JNICALL
Java_FirstJNI_displayOther(JNIEnv *env, jobject obj)
{
printf("Hello world! This is Other Function.\n");
}

JNIEXPORT jstring JNICALL
Java_FirstJNI_getLine(JNIEnv *env, jobject obj, jstring enter)
{
char buf[128];
const char *str = (*env)->GetStringUTFChars(env, enter, 0);
printf("%s", str);
(*env)->ReleaseStringUTFChars(env, enter, str);

scanf("%s", buf);
return (*env)->NewStringUTF(env, buf);
}

I am building them with the following commands:

/usr/java/jdk1.5.0_08/bin/javac FirstJNI.java
/usr/java/jdk1.5.0_08/bin/javah -jni FirstJNI
gcc -O2 -I/usr/java/jdk1.5.0_08/include
-I/usr/java/jdk1.5.0_08/include/linux -fno-strict-aliasing -fPIC
-fno-omit-frame-pointer -W -Wall -Wno-unused -Wno-parentheses -c FirstJNI.c
gcc -Wl,-soname=libFirstJNI.so -shared-libgcc -lc -shared -o
libFirstJNI.so FirstJNI.o

If I then try and run it (after setting my LD_LIBRARY_PATH) I get:

[hsr@palain8 jni]$ /usr/java/jdk1.5.0_08/bin/java FirstJNI
in static
Exception in thread "main" java.lang.UnsatisfiedLinkError:
/users/hsr/apache-tomcat-4.1.32/webapps/perf/jni/libFirstJNI.so:
/users/hsr/apache-tomcat-4.1.32/webapps/perf/jni/libFirstJNI.so: cannot
open shared object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at FirstJNI.<clinit>(FirstJNI.java:9)

This is strange since it is giving me a fully qualified path and if I do
an ls of that path the file is there. So, just for fun I removed the
file, tried again and got:

[hsr@palain8 jni]$ /usr/java/jdk1.5.0_08/bin/java FirstJNI
in static
Exception in thread "main" java.lang.UnsatisfiedLinkError: no FirstJNI
in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at FirstJNI.<clinit>(FirstJNI.java:9)

This indicates to me that in the first example it really knew the file
was there and that there was something else wrong. Next I went to the
demo directory of the java 1.5.0_8 install and grabbed an .so file out
of there and copied t to my directory. Now I get:

[hsr@palain8 jni]$ /usr/java/jdk1.5.0_08/bin/java FirstJNI
in static
entered main
creating new FirstJNI
Exception in thread "main" java.lang.UnsatisfiedLinkError: displayHelloWorld
at FirstJNI.displayHelloWorld(Native Method)
at FirstJNI.main(FirstJNI.java:20)

This is exactly what I would expect and the fact that this time it found
the .so indicates to me that it has nothing to do with my misnaming the
methods. So, I can only conclude that it is seeing my .so but not
recognizing it as valid which indicates that I am not linking it correctly.

After this long winded posting does anyone have any words of wisdom or
suggestions?

Thanks

Howard

Gordon Beaton

unread,
Jan 24, 2007, 4:34:16 PM1/24/07
to
On Wed, 24 Jan 2007 14:18:12 -0500, Howard wrote:
> I am having a problem getting JNI to work on Linux. I think it is
> with how I am creating the shared object file.

[...]

> I am building them with the following commands:
>
> /usr/java/jdk1.5.0_08/bin/javac FirstJNI.java
> /usr/java/jdk1.5.0_08/bin/javah -jni FirstJNI

There's no need to specify -jni here.

> gcc -O2 -I/usr/java/jdk1.5.0_08/include
> -I/usr/java/jdk1.5.0_08/include/linux -fno-strict-aliasing -fPIC
> -fno-omit-frame-pointer -W -Wall -Wno-unused -Wno-parentheses -c FirstJNI.c
> gcc -Wl,-soname=libFirstJNI.so -shared-libgcc -lc -shared -o
> libFirstJNI.so FirstJNI.o

What do "file" and "ldd" tell you about the library?

Try compiling and linking like this instead:

gcc -Wall -O2 -fPIC -I $JDK/include -I $JDK/include/linux -o FirstJNI.c
gcc -shared FirstJNI.o -o libFirstJNI.so

or all in one step:

gcc -Wall -O2 -fPIC -shared -I $JDK/include -I $JDK/include/linux
FirstJNI.c -o libFirstJNI.so

/gordon

--
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e

Howard

unread,
Jan 24, 2007, 3:22:00 PM1/24/07
to
I figured it out. What I did not mention is hat I am running on an
Opteron 64 bit system. When I went to the Sun web site to get java
1.5.0_8 they had a note next to the Amd64 version saying "use 32 bit
version for applet and Java Web Start support" so, since I am working on
some .jsp pages that I downloaded the i586 version. I tried downloading
the amd64 version and it now works fine. I recompiled my java for the
.jsp pages and they still seem to work too. :)

Thanks

Howard

0 new messages