Reputation: 4021
Firstly, my example has the following directory structure:
Sample.c
lib/
mypackage/
--Sample.java
Sample.java
in mypackage
looks like this:
package mypackage;
public class Sample {
public static native int sampleMethod(int x);
public static void main(String[] args) {
System.loadLibrary("Sample");
System.out.println("sampleMethod result: " + sampleMethod(5));
}
}
I run javac mypackage/Sample.java
to compile the java file and javah mypackage.Sample
to generate the JNI
headers. Then I compile the library using the following command:
clang -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/darwin" -o lib/libSample.so -shared Sample.c
At this point the directory structure looks like this:
Sample.c
mypackage_Sample.h
lib/
--libSample.so
mypackage/
--Sample.java
--Sample.class
Now when I try to run the example using java -Djava.library.path=./lib/ mypackage.Sample
I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at mypackage.Sample.main(Sample.java:7)
I tried specifying the full path to lib/
, but I get the same error.
I am not sure if the code for the header and the implementation matter, but I will post them anyway.
mypackage_Sample.h
:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mypackage_Sample */
#ifndef _Included_mypackage_Sample
#define _Included_mypackage_Sample
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mypackage_Sample
* Method: sampleMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_mypackage_Sample_sampleMethod
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
Sample.c
:
#include "mypackage_Sample.h"
#include <stdio.h>
JNIEXPORT jint JNICALL Java_mypackage_Sample_sampleMethod
(JNIEnv * env, jclass obj, jint num) {
return num * num;
}
I run this on OS X Yosemite 10.10.5
using clang 7.0.2
and java 1.8.0_101
.
Upvotes: 1
Views: 752
Reputation: 33845
It looks like you have the wrong name from your library file (libSample.so
).
If you use:
System.loadLibrary("Sample");
The JVM will map this name to a platform specific file name to try and load. On Linux that is libSample.so
, on Windows that is Sample.dll
, but on OS X it's something else.
You can find out which name your library file should have by looking at the output of:
System.mapLibraryName("Sample");
Called on the target platform.
After that, you can use that as the name of your library file.
Upvotes: 1