views:

2148

answers:

4

Hey all,

JNI on Ubuntu 8.10 using Eclipse and gcc (Standard with Ubuntu if there are flavours) i can't seem to load my library despite the make file creating it succesfully.

The main java class is as follows;

class Hello {
    public native void sayHello();

    static {
        System.loadLibrary("hello.so");
    }

    public static void main(String[] args) {
        Hello h = new Hello();
        h.sayHello();
    }
}

My make file is as such;

    all : hello.so

hello.so : Hello.o
    gcc -shared -o hello.so Hello.o

Hello.o : Hello.c Hello.h
    gcc -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -c Hello.c -o Hello.o

Hello.h : Hello.class
    javah -jni Hello

clean :
    -del Hello.h
    -del Hello.o

The rest of the code can be found on my project page (code.google.com/p/miffed/source/browse/#svn/trunk/JNI), there isn't much more but I'd rather keep the length of this query down.

The error I'm getting is as follows;

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello.so in java.library.path

If I use an explicit path;

System.loadLibrary("/home/gavin/Work/workspace/JNI/hello.so");

Then it works, but I'd much rather not use an explicit path if possible.

Thanks in advance!!

Gavin

+1  A: 

And are you running it with something like:

java -Djava.library.path=/home/gavin/Work/workspace/JNI Hello

You'll need to make sure the shared object is in your library path.

paxdiablo
+1  A: 

You're calling System.loadLibrary() incorrect. The loadLibrary method takes a library name, e.g. "hello", and tries to load the corresponding shared object. On Unix, it will attempt to load "libhello.so", and on windows it will try to load "hello.dll". It will expect the file to be found in java.library.path.

The method you probably intend to be calling is System.load() which takes a fully qualified filename and loads it. This method should take a File as argument, but it takes a string instead. If you use load, you'll have to handle local naming conventions manually, but you won't have to rely on java.library.path to be set.

JesperE
+1  A: 

As per Pax you should set the library path to where ever Java should look for the library. Your library name should be libhello.so. The call to load the library should then be:

System.loadLibrary("hello");

Linux libraries are referenced by the convention lib**name**.so and loaded based on the name. Here is a link about dynamic linking problems in Java from the SWIG documentation, although you are not using SWIG this section is still relevant.

Daniel Nesbitt
+1  A: 

do the following:

1/ change your java class to

class Hello {

public native void sayHello();

static {
    System.loadLibrary("hello");
}

public static void main(String[] args) {
    Hello h = new Hello();
    h.sayHello();
}

}

2/ rename hello.so to libhello.so: "cp hello.so libhello.so" or "mv hello.so libhello.so"

3/ run as: "java -Djava.library.path=/home/gavin/Work/workspace/JNI/ Hello"

Nick