15

I've seen this question on here, tried the proposed fixes, but no success so far for me. I have quite some Java experience, but JNI is a long time ago, never did it on Linux though...

I'm trying to get a simple HelloWorld JNI app running on Linux.

Small java file:

class HelloWorld {

    private native void print();

    public static void main(String[] args){
        new HelloWorld().print();
    }

    static {
        System.out.println(System.getProperty("java.library.path"));
        System.loadLibrary("HelloWorld");
    }

}

Small C file:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"

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

compiled the C file by:

gcc -shared -Wall -fPIC HelloWorld.c -I/usr/lib/gcc/x86_64-redhat-linux/3.4.3/include/ -o libHelloWorld.so

Run the app by:

java HelloWorld

or

java -Djava.library.path=/home/nxp40954/jnitesting/. HelloWorld

But no good, getting a:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/nxp40954/jnitesting/libHelloWorld.so: /home/nxp40954/jnitesting/libHelloWorld.so: cannot open shared object file: No such file or directory

Strange, because there is actually a /home/nxp40954/jnitesting/libHelloWorld.so file.

Does anyone have a clue?

Stuart Cook
  • 3,994
  • 25
  • 23
Vlemmix
  • 151
  • 1
  • 1
  • 3

3 Answers3

14

execute this way:

export LD_LIBRARY_PATH=.
java HelloWorld

The java.lang.UnsatisfiedLinkError is thrown when the .so file cannot be loaded. The LD_LIBRARY_PATH variable points extra location to look for the *.so files.

I'm on 32bit ubuntu with sun java. I was compiling this way:

gcc -shared -Wall -fPIC HelloWorld.c -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-sun-1.6.0.26/include/linux -o libHelloWorld.so
Michał Šrajer
  • 30,364
  • 7
  • 62
  • 85
  • Yes, I know that libs should go the path that's defined by LD_LIBRARY_PATH, "." is also in there, and even by using the -Djava.library.path=/home/nxp40954/jnitesting I explicitly define where the libHelloWorld.so is located, but I still get this "No such file or directory" error. – Vlemmix Sep 02 '11 at 14:44
  • I compiled your code and it works for me. Can you try to do it all in one directory and use "." ? BTW, what java are you using? Waht OS? – Michał Šrajer Sep 02 '11 at 14:56
5

Your example worked for me on a 32-bit Linux installation.

Is your shared library compiled as a 32-bit or 64-bit shared library? Check with command file libHelloWorld.so. If your shared library is 64-bit then you need to give command line option -d64 when starting Java so that Java can load the 64-bit shared library.

If your shared library is 32-bit then perhaps the Java option -d32 will solve the problem.

Simon C
  • 1,977
  • 11
  • 14
  • Thanks man! Should have thought about that. No 64-bit JVM support, but the lib was 64-bit. Added the -m32 parameter to gcc, all ok not. Thanks! – Vlemmix Sep 02 '11 at 15:23
  • 2
    On the off-chance this doesn't work for you like me, make sure you specify `LD_LIBRARY_PATH` environment variable as per Michal's answer instead of Java's `java.library.path`. This is because if your linked library needs to access another linked library it will not be able to find it since it doesn't know about `java.library.path`. – Molten Ice Feb 24 '16 at 16:43
1

Clarification on java.library.path and system path:

java.library.path is a JVM-Variable which can be set - e.g. - by the command line parameter

-Djava.library.path=xy

DLL's (on windows) and so's (on linux) which are loaded by the java call loadLibrary() must be located in the java.library.path. If it is loaded via JNI it must be located in the system path.

If such a linked library loads another linked library, latter must be found in the system path. In Windows the system path is resolved against the PATH environment variable, in linux it's the LD_LIBRARY_PATH environment variable (for linked libraries).

Another point to ensure in linux: Verify that the linked library has executable permissions for the current user. Usually a

sudo chmod 755 myLinkedLib

does the trick.

Heri
  • 4,368
  • 1
  • 31
  • 51