I get this error from testing JNI:
Undefined symbols for architecture x86_64:
"_JNI_CreateJavaVM", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here is c++ code:
#include <jni.h>
#include <iostream>
using namespace std;
int main()
{
int res;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
JavaVM *jvm;
JNIEnv *env;
jmethodID mid;
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path = /Users/stephen/course/test/Test";
options[2].optionString = "-verbose:NONE";
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
res = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
if(res == JNI_ERR){
cout << "Error invoking the JVM";
return 1;
}
cout <<"create JVM successfully!"<<endl;
jclass cls = env->FindClass("/Users/stephen/course/Qt-project/test/Test");
if(cls != 0){
cout<<"find class successfully!" << endl;
}
mid = env->GetMethodID(cls,"sayHello","stephen");
if(mid != 0){
cout<<"Invoke method successfully!" << endl;
}
jvm->DestroyJavaVM();
return 0;
}
Here is java code:
public class Test
{
public static void sayHello(String s){
System.out.print("hello I am" + s + "\n");
}
}
I add the include path of " jdk/include; jdk/include/darwin" the project, also I add lib path of " jdk/jre/lib/server" to the project to get the libjvm.dylib. The c++ standard library of my project is libstdc++(gnu c++ standard library. But I can't solve this problem as expected.
Take a look here for a sample code where JVM library is linked with your project:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo028
Take a look at Makefile. Especially, here:
main: recipeNo028_main.o
ld -o lib/recipeNo028_main -L${JAVA_HOME}/jre/lib/server/ \
-ljvm \
$(MAC_OS_FLAGS) \
lib/recipeNo028_main.o
where jvm lib is linked with the code, and here:
CC=llvm-gcc
MAC_OS_FLAGS=-rpath ${JAVA_HOME}/jre/lib/server -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -lSystem
where all required libs are added to your code as well. It should work. Try to compile sample code. You can find more samples here: http://jnicookbook.owsiak.org
Update
How to use arbitrary JDK version for compilation.
First, take a look at all installations you have
/usr/libexec/java_home -V
This will produce something like this
/usr/libexec/java_home -V
Matching Java Virtual Machines (4):
9, x86_64: "Java SE 9" /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
1.8.0_144, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
1.8.0_111, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
1.7.0_80, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
Then, before running make
, simply set JAVA_HOME
to whatever you like
export JAVA_HOME=$(/usr/libexec/java_home -v 9)
Now, your code will use version that you have chosen.