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

[1315 byte] By [AndreiStoiculescua] at [2007-11-27 5:24:07]
# 1
Hi Andrei!I succesfully migrate some JNI related code after reading this tutorial: http://ringlord.com/publications/jni-howto/[]'s.
dekasseguia at 2007-7-12 11:50:17 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 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.

Niceguy1a at 2007-7-12 11:50:17 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3

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 ).

I am looking forward to your reply

Thanks,

Andrei

AndreiStoiculescua at 2007-7-12 11:50:17 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 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.

Niceguy1a at 2007-7-12 11:50:17 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 5

HI Jim,

I finally found a workaround : setting the LD_LIBRARY_PATH like this :

LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/i386

export LD_LIBRARY_PATH

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/i386/client

export LD_LIBRARY_PATH

I have read some more on this forum, and it seems it is a sort of a bug from SUN...

Anyway, for now it's true : Calling Java from C on Ubuntu :)

Thank you all !

Andrei

AndreiStoiculescua at 2007-7-12 11:50:17 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 6
Anyway, if someone can shed light upon this matter and explain in detail the ins and outs, it would be great.Andrei
AndreiStoiculescua at 2007-7-12 11:50:17 > top of Java-index,Java HotSpot Virtual Machine,Specifications...