Reputation: 995
I have the exact same code as Trouble with compiling JNI. In fact, had the same issue. Tried solving using the two step approach, which is running the following:
cc -c HelloWorld.c
Then the next command:
cc -shared -o libHelloWorld.so HelloWorld.o
The first one runs find and creates HelloWorld.o, however, after running the second command, I get this error:
/usr/bin/ld: /tmp/ccA9BIT2.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /tmp/ccA9BIT2.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status
I'm running an ubuntu 16.04 and JDK version 8
Any ideas?
Upvotes: 0
Views: 1300
Reputation: 13375
If you start your experience with JNI, it's always good to start with super simple - preferably "Hello world" - sample. This way, you can make sure all the elements in the chain are working as expected.
Start with simple class (it's good idea to put it inside package):
package recipeNo001;
public class HelloWorld {
/* This is the native method we want to call */
public static native void displayMessage();
/* Inside static block we will load shared library */
static {
System.loadLibrary("HelloWorld");
}
public static void main(String[] args) {
/* Call to shared library */
HelloWorld.displayMessage();
}
}
You will also need native code itself. Make it as simple as possible
#include <stdio.h>
#include "jni.h"
JNIEXPORT void JNICALL Java_recipeNo001_HelloWorld_displayMessage
(JNIEnv *env, jclass obj) {
printf("Hello world!\n");
}
Note that JNI has a fixed naming convention when it comes to names of the functions: Resolving Native Method Names
Then, you can compile everything:
${JAVA_HOME}/bin/javac -d target java/recipeNo001/HelloWorld.java
-d
means that classes will be compiled inside directory target
cc -g -shared -fpic -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/$(ARCH) HelloWorld.c \
-o lib/libHelloWorld.so
Once everything is compiled, you can simply run the sample:
${JAVA_HOME}/bin/java \
-Djava.library.path=${LD_LIBRARY_PATH}:./lib \
-cp target recipeNo001.HelloWorld
Note that we are setting class path with -cp
because class files were generated inside target
directory.
That's it :) You can find more samples here: JNI Cookbook
Upvotes: 1