Calling JNI from C under Linux(Ubuntu)
Hello everyone,
I am having problems with calling JNI code from C under Ubuntu, and I would very much appreciate your help.
I understand there are two things to be done for this to work :
1 include the jni.h header file
2 set the path to the jvm "executable" in the system path.
Currently, I have made it work from Windows, through using the Microsoft Visual Studio; the 2 above mentioned steps were not enough though, as I needed to add the jvm.dll to the project; only then it worked.
I am trying to find the Linux equivalent; for this I have downloaded jdk1.6.0_01 for Linux, (I was using the same version on Windows) but it is not very clear to me which is the Linux equivalent for jvm.dll; this is why I have added a lot of subdirectories to the system path (like jre/bin or jre/lib/i386/client etc. ( the instruction I used is PATH=...........:$PATH )
After this, I have tryed to build a makefile, but I don't think I have done a good job (I am new to Linux).
After lots of tries, with different makefiles, and all the above added I keep getting the error : "undefined reference to JNI_createJavaVM" which I suspect means I haven't set the path to the right jvm file.
I would really really appreciate some help....
Thank you,
Andrei
# 2
> Hello everyone,
>
> I am having problems with calling JNI code from C
> under Ubuntu, and I would very much appreciate your
> help.
>
> I understand there are two things to be done for this
> to work :
> 1 include the jni.h header file
> 2 set the path to the jvm "executable" in the system
> path.
>
> Currently, I have made it work from Windows, through
> using the Microsoft Visual Studio; the 2 above
> mentioned steps were not enough though, as I needed
> to add the jvm.dll to the project; only then it
> worked.
You need to do the same sort of thing in Linux. This is only required because you want to use the Invocation API. Regular JNI, where you call native methods from Java code does not require that you link with the jvm shared library.
>
> I am trying to find the Linux equivalent; for this I
> have downloaded jdk1.6.0_01 for Linux, (I was using
> the same version on Windows) but it is not very clear
> to me which is the Linux equivalent for jvm.dll; this
> is why I have added a lot of subdirectories to the
> system path (like jre/bin or jre/lib/i386/client etc.
> ( the instruction I used is PATH=...........:$PATH )
>
> After this, I have tryed to build a makefile, but I
> don't think I have done a good job (I am new to
> Linux).
>
> After lots of tries, with different makefiles, and
> all the above added I keep getting the error :
> "undefined reference to JNI_createJavaVM" which I
> suspect means I haven't set the path to the right jvm
> file.
No. This means the compiler was unable to link the references to CreateJavaVM in your code to the actual implementation of CreateJavaVM, which is found in the JVM shared libraries. Your PATH has nothing to do with it.
Here's a quick example I just tested on my Mandriva Linux machine:
==========Java Code==============
public class Invokee {
public static void invoke() {
System.out.println("Hello World!");
}
}
==============C Code================
#include "jni.h"
int main() {
JNIEnv *env;
JavaVM *vm;
jint res;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_TRUE;
res = JNI_CreateJavaVM(&vm, (void**)&env, &vm_args);
jclass invokeeClass = (*env)->FindClass(env, "Invokee");
if (invokeeClass == NULL) {
printf("Failed to find Invokee class");
return -1;
}
jmethodID invokeID = (*env)->GetStaticMethodID(env, invokeeClass, "invoke", "()V");
if (invokeID == NULL) {
printf("Failed to find invoke() method");
return -1;
}
(*env)->CallStaticVoidMethod(env, invokeeClass, invokeID);
return 0;
}
======================================
The C code is compiled with the following command. Note the bit at the end:
gcc -o invoke -I/usr/java/jdk1.6.0_01/include -I/usr/java/jdk1.6.0_01/include/linux invoke.c /usr/java/jdk1.6.0_01/jre/lib/i386/server/libjvm.so
Locate libjvm.so on your machine and point gcc to it. It will take care of the rest.
Jim S.
# 4
> Hi Jim,
>
> Thank you very much for the instructions; very
> helpfull, and I think very close to working. Just one
> problem left; the code compiles good, and the
> executable is created, but when I try to run it I am
> getting the error :
>
> "error while loading shared libraries : libjvm.so:
> cannot open shared object file : no such file or
> directory"
>
> which is a little strange, as the location is
> defently valid since it passes the compilation
> without any errors ( I have been careful to point to
> the right location ).
What does
java -version
output?
Since you said you added a variety of things to the system path to try to compile the code, you may have caused a problem for the java executable.