|
Comments and Discussions
|
 |
|
 |
Great article and good code that helped me a lot.
|
|
|
|
 |
Hi,
My JDK version is 1.7.0_05,I am trying to make a call from a c++ application to
a java method. But JNI_VERSION_1_7 is not present in jni.h.
Then what should I set as VERSION ?
Thanks,
Debanka
|
|
|
|
 |
Hi,
The JDK version is different from that of the JNI. So JNI_VERSION_1_6 is also right for u.
May it useful for u.
Eiwin
|
|
|
|
 |
can we call a java metod from a jar library from c++ code, if yes how do we do it
|
|
|
|
 |
Calling Java from C:
https://dl.dropbox.com/u/46434672/Code/JniTest.zip
|
|
|
|
 |
HI,
I am getting error unable to launch JVM in this code after compiling.
Please tell me where i did wrong ..
|
|
|
|
 |
Hi
When i Compiled VC++ code I got An error "program can't start becouse jvm.dll is missing from your computer " Please tell me what should i do to resolve it .
java 6 and VC++ 2008 are already installed in MY pC.
Regards
Gupta Rahul
|
|
|
|
 |
Very easy for getting started. congratulations and thank you.
|
|
|
|
 |
I have set my path variable as below.. PATH=D:\oracle\product\10.2.0\client_1\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WIN DOWS\System32\Wbem;C:\Program Files\IBM\RationalSDLC\ClearCase\bin;C:\Program Fi les\IBM\RationalSDLC\common;C:\Program Files\TortoiseSVN\bin;D:\jdk1.6.0_31\lib; D:\jdk1.6.0_31\jre\bin\client;D:\jdk1.6.0_31\bin
I have set my include and library path in my project setting... My program has been compiled successfully but unable to execute. It gives the following error while executing the following. ---------------------------------------------------------------- Error occurred during initialization of VM Unable to load native library: Can't find dependent libraries ---------------------------------------------------------------- suggest me the changes... ggggggggggggggggggggggggggggggggggggggggggggggggg
|
|
|
|
 |
The example provided by you is very useful and it has worked wonders for me . Now the problem is that if I am using a Java file with a package included in it but then the findclass function returns nothing so what changes should a make in the java file as its important for me to include the package.
|
|
|
|
 |
I get -1 when i`m trying to run the
JNI_CreateJavaVM,
I feel like i have tried everything with pats, please help me figure this out! That would be appreciated!
code:
JavaVM* jvm;
JNIEnv* env;
JavaVMInitArgs args;
JavaVMOption options[1];
args.version = JNI_VERSION_1_4; // JNI_VERSION_1_2 is interchangeable for this example
args.nOptions = 1;
options[0].optionString = "-Djava.class.path=:C://i have put the Path to the java sourcecode here
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;
int en = JNI_CreateJavaVM(&jvm;, (void **)&env, &args) // THIS RETURNS -1
PATH:
C:\Program Files\Java\jdk1.6.0_27\jre\bin\client;C:\Modeltech_pe_edu_10.0c\win32pe_edu;C:\Program Files\Java\jdk1.6.0_27\bin;;C:\Windows\System32\jvm.lib;C:\Program Files\Java\jdk1.6.0_27\jre\bin;C:\Program Files\Java\jre6\bin\client\jvm.dll;C:\Program Files\Java\jdk1.6.0_27\lib;C:\Program Files\Java\jre6\bin\client;\jvm.lib
system Path: C:\Program Files\Java\jdk1.6.0_18\jre\bin\client; Live\Shared;C:\VXIPNP\WinNT\Bin\VXIPNP\WinNT\Binnnn;%ANT_HOME%\binVXIPNP\WinNT\Bin\VXIPNP\WinNT\Bin;%ANT_HOME%\binVXIPNP\WinNT\Bin\VXIPNP\WinNT\Binn;%ANT_HOME%\binVXIPNP\WinNT\Bin\VXIPNP\WinNT\Bin;%ANT_HOME%\binVXIPNP\WinNT\Bin\VXIPNP\WinNT\Binnnn;%ANT_HOME%\binVXIPNP\WinNT\Bin\VXIPNP\WinNT\Bin;%ANT_HOME%\binVXIPNP\WinNT\Bin\VXIPNP\WinNT\Binn;%ANT_HOME%\binVXIPNP\WinNT\Bin\VXIPNP\WinNT\Bin;%ANT_HOME%\bin;%JAVA_HOME%\bin;%ANT_HOME%\bin;%JAVA_HOME%\bin;%ANT_HOME%\bin;%JAVA_HOME%\bin;%ANT_HOME%\bin;%JAVA_HOME%\bin;%SystemRoot%\System32;%SystemRoot%;%SystemRoot%\System32\Wibem\;C:\Program Files\Java\jdk1.6.0_27\jre\bin\client
JAVA_HOME: C:\Program Files\Java\jdk1.6.0_27;C:\Program Files\Java\jdk1.6.0_27\jre\bin\server;C:\Program Files\Java\jdk1.6.0_27\jre\bin\client
Regards Ann
|
|
|
|
 |
Have you created your java classes? options[0].optionString should have the location of the java class files rather than java sources.
|
|
|
|
 |
I've compiled and built the program without errors, but the program quits when it gets to the line:
int ret = JNI_CreateJavaVM(jvm, (void**)&env;, &vm;_args);
which is in the method:
JNIEnv* create_vm(JavaVM ** jvm)
There are no error messages of any kind, it just doesn't work. I've used some print statements which appear in the console box and break points to find where exactly it stops and I'm pretty sure it's that line. The Output tab shows this:
'CTest.exe': Loaded 'G:\UniPrograms\VsProjects\src_CJNIJava\CTest\Debug\CTest.exe', Symbols loaded.
'CTest.exe': Loaded 'C:\Windows\System32\ntdll.dll'
'CTest.exe': Loaded 'C:\Windows\System32\kernel32.dll'
'CTest.exe': Loaded 'G:\UniPrograms\VsProjects\src_CJNIJava\CTest\jvm.dll'
'CTest.exe': Loaded 'C:\Windows\System32\user32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\gdi32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\advapi32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\rpcrt4.dll'
'CTest.exe': Loaded 'C:\Windows\System32\wsock32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\ws2_32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\msvcrt.dll'
'CTest.exe': Loaded 'C:\Windows\System32\nsi.dll'
'CTest.exe': Loaded 'C:\Windows\System32\winmm.dll'
'CTest.exe': Loaded 'C:\Windows\System32\ole32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\oleaut32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\oleacc.dll'
'CTest.exe': Loaded 'C:\Windows\System32\psapi.dll'
'CTest.exe': Loaded 'C:\Windows\System32\msvcr100.dll', Symbols loaded.
'CTest.exe': Loaded 'C:\Windows\System32\imm32.dll'
'CTest.exe': Loaded 'C:\Windows\System32\msctf.dll'
'CTest.exe': Loaded 'C:\Windows\System32\lpk.dll'
'CTest.exe': Loaded 'C:\Windows\System32\usp10.dll'
The program '[5096] CTest.exe: Native' has exited with code 1 (0x1).
I'm using Microsoft Visual Studio 2008 and Windows Vista.
If anyone has any ideas, please let me know.
|
|
|
|
 |
I have the exact same problem... Using VS 2010 and Windows 7.
|
|
|
|
 |
I'm having the same problem too.
VS 2010 and Windows 7.
|
|
|
|
 |
Hello,
i have a guess why
try "ret = JNI_CreateJavaVM(&jvm, (void **)&env;, &vm;_args);" i think there have to be a "&" before "jvm"
Please let me know if it helps you out.
best regards m2e
|
|
|
|
 |
tcc: undefined symbol JNI_CreateJavaVM@12 .i m getting this issue. please help me out.
|
|
|
|
 |
1- After some other bugs already discussed in this thread, there are also other memory leak problems: All references to env->NewStringUTF or similar construction must be released after used, or a memory leak will occur snippet 1: jstring StringArg = env->NewStringUTF("\nTestCall:Called from the C Program\n"); //Calling another static method and passing string type parameter env->CallStaticVoidMethod(clsH,midCalling,StringArg); snippet 1 workaround should be: jstring StringArg = env->NewStringUTF("\nTestCall:Called from the C Program\n"); //Calling another static method and passing string type parameter env->CallStaticVoidMethod(clsH,midCalling,StringArg); env->DeleteLocalRef(StringArg); The memory leak can be easily seen if looping this snippet 1 sequence for a long long time, the NewStringUTF will return null after some times (after 2,700,000 loops on my system). This can also be seen under windows by looking at free memory melting constantly under task manager. When the workaround is used, this problem does not happens anymore...
|
|
|
|
 |
Very good but some bugs to fix
|
|
|
|
 |
The example gave me the missing link while searching for a way to use Java-classes/code from inside C/C++-programs. Thanks! Now I'm still searching for a wrapper-generator that is able to generate the C++-Interface and mapping-code from a set of Java-classfiles. The other way round (calling C/C++ from inside Java) 'swig' ist the tool to do this. There are many more wrapper-generator besides swig but they all only wrap native code to Java. Does anyone have any suggestions? Thanks Ulf
|
|
|
|
 |
thank you for your sample.
But I meet some problem while compiling the sample code under WindowsXp though at last success run it.
So I just write here for others:
1. ControlNEDetail.java should be rename to ControlDetail.java
2. under "Java Src\TestStruct" directory, call "javac *.java" to generate class files
3. add include and link path to the project settings
4. add jvm.dll path(like d:\Java\jdk1.6.0_24\jre\bin\client) to PATH
|
|
|
|
 |
I noticed that too.
By the way I don't THINK the jvm.dll is needed. Including the path seems to give errors - memory location (of file) is corrupted and similar. No idea what to do about it though. My program suddenly started compiling successfully without including the jvm, but I've got a different error now (see post above).
|
|
|
|
 |
I am trying to run this example in linux and am getting the error message:
Unable to find the requested class.
It looks the classpath is not being set correctly. Is this is a valid path : "/home/username/java/JNI/JavaSrc/TestStruct/src" ? I got previous classpath (getenv("CLASSPATH");) from and added it to the classpath when creating the JVM, and am still getting the above error message when accessing the HelloWorld class (clsH = env->FindClass("HelloWorld");), clsH is null.
what am I doing wrong ? How do I debug this ?
Thanks
arnott
|
|
|
|
 |
you need call javac to compile these .java files to generate .class files
and don't forget to rename ControlNEDetail.java to ControlDetail.java
|
|
|
|
 |
how can i debug jni code....so that i can see variable values at run time
One more doubt..
if my signature of java method is as shown below
Signature: (Ljava/lang/String;)[Ljava/lang/String;
then how to call that method like for example CallVoidMethod
how to handle return values
modified on Wednesday, February 2, 2011 2:01 AM
|
|
|
|
 |
Hi,
I have the .c code from the example.
I run this command for compile:g++ -o Invoke -I<.h files path> -L\jvm.lib -L\jvm.dll Invoke.cpp
I tried without -L\jvml.dll or put only -L
And I get the same error:
reference to _imp_JNI_CreateJavaVM@12 is undefined
reference to WinMain@16 is undefined
I use minGW as a gcc compiler for windows.
Regards
Rodrigo
|
|
|
|
 |
Excellent explanation of his code...
|
|
|
|
 |
This is by far one of the best articles I have ever come across.
|
|
|
|
|
 |
Hi midiman,
Could you please help me to make this article good and more useful for others?
Suggestions and ideas are highly appreciated.
Thanks,
Ahmad Jalil Qarshi
|
|
|
|
 |
A very good guide, cheers man.
|
|
|
|
 |
Thank you very much for your example, it was a great help. However, I had a little bit of trouble getting it compile and run under GNU/Linux (OpenSuse), so I thought I'd write what I needed to do in case anyone else ran into the same problems. I compiled using GCC. First, I needed to make sure that the right header file (`jni.h') was found. I had both Sun Java and the GNU Java Compiler installed and I was getting an error message about a conflict. I uninstalled the GNU Java package, although this probably wasn't necessary. If you do this, make sure you uninstall the "development" package or the header files will remain. Then, I had a problem because the linker couldn't find the shared library file `libjvm.so'. The trick is, you have to provide the path using the `-L' option _and_ set `LD_LIBRARY_PATH', i.e., export LD_LIBRARY_PATH=<Path to library>:<Another path, if necessary> # etc., Paths separated by `:' g++ -o <Name of executable file> -I<Path to header files 1> -I<Path the header files 2> -L<Path to shared library file 1> -L<Path to shared library file 2> CTest.cpp (The -I and -L options are used as many times as needed.) I don't know why just using the `-L' option without setting `LD_LIBRARY_PATH' is not sufficient. For example, this finally worked for me: export LD_LIBRARY_PATH=/usr/lib64/jvm/java-1.6.0-sun-1.6.0/jre/lib/amd64/server/:/usr/lib64/jvm/java-1.6.0-sun-1.6.0/jre/lib/amd64/ g++ -I/usr/lib64/jvm/java-1.6.0-sun-1.6.0/include/ -I/usr/lib64/jvm/java-1.6.0-sun-1.6.0/include/linux -L$LD_LIBRARY_PATH -L/usr/lib64/jvm/java-1.6.0-sun-1.6.0/jre/lib/amd64/server/ -L/usr/lib64/jvm/java-1.6.0-sun-1.6.0/jre/lib/amd64/ -ljvm CTest.cpp This little makefile makes things a bit neater: #### Makefile INCLUDE_FLAGS := -I/usr/lib64/jvm/java-1.6.0-sun-1.6.0/include/ -I/usr/lib64/jvm/java-1.6.0-sun-1.6.0/include/linux LD_FLAGS := -L/usr/lib64/jvm/java-1.6.0-sun-1.6.0/jre/lib/amd64/server/ -L/usr/lib64/jvm/java-1.6.0-sun-1.6.0/jre/lib/amd64/ LIB_FLAGS := -ljvm ctest: CTest.cpp g++ -o ctest ${INCLUDE_FLAGS} ${LD_FLAGS} ${LIB_FLAGS} CTest.cpp If you don't know where your header files or shared library files are, you can use `find' to find them. Header files are usually under `/usr/include' or in some other `include/' directory. The names of shared library files start with `lib' and usually (always?) end in `.so'. They can be found using `find . -name "lib*.so"' from the shell. `find' searches starting in the working directory and working its way downward. `/usr/' or `/usr/local/' is usually a good place to start. I hope this saves somebody a long search through the Internet. Laurence Finston
|
|
|
|
 |
Thanks Laurence,
The information you provided is very useful for other people because 80% of people who try to use this code face compilation problem. Your comments will help them.
Thanks again.
Ahmad Jalil Qarshi
|
|
|
|
 |
Thank you, Ahmad. I've started working through your example slowly. If I think of anything I think might be helpful, I'll post it here. One thing I'm not sure about is how it would work to call the non-static methods. (I'm much more familiar with C and C++ than Java.) Correction: I wrote: "`find' searches starting in the working directory and working its way downward." This is false. It starts at the directory given in the first argument and works its way downward. In the example, I wrote `find . -name "<name>"', where `.' refers to the working directory. An absolute or relative path could be used instead, e.g., `find /usr/local/ -name "some.file"'. Laurence
|
|
|
|
 |
A couple more notes on compiling under GNU/Linux with GCC: There are some things that are specific to Microsoft (or .NET?) and can be removed: In CTest.cpp: The line #include "StdAfx.h" can be removed or commented-out. The following files are not needed: CTest.dsp CTest.dsw CTest.ncb CTest.plg StdAfx.cpp StdAfx.h CTest.opt Nor is the directory `Debug/'. I got the following warning: In function ‘JNIEnv* create_vm(JavaVM**)’: CTest.cpp:39: warning: deprecated conversion from string constant to ‘char*’ To get rid of it, all you have to do is add the following line outside of any function before the definition of `create_vm': char temp_str[] = "-Djava.class.path=<Your path>"; e.g., char temp_str[] = "-Djava.class.path=/home/some_user/jni_test/Java_Src/TestStruct"; Then, in the definition of `create_vm', set `options.optionString' this way: options.optionString = temp_str; // Path to the java source code `JavaVMOption' is declared like this in `jni.h': typedef struct JavaVMOption { char *optionString; void *extraInfo; } JavaVMOption; That is, `JavaVMOption.optionString' is a pointer to `char' and no memory has been reserved for the string it's supposed to point to. Declaring `temp_str' as a character array causes memory to be reserved in static storage, which will exist until the process finishes. The assignment `options.optionString = temp_str;' stores the _address_ of `temp_str' in the pointer object `options.optionString'. Laurence
|
|
|
|
 |
I wrote: "One thing I'm not sure about is how it would work to call the non-static methods." This is no problem at all! In `class ControlDetail', I added following method: public int test_func() { System.out.println("\nThis is `ControlDetail::test_func'.\n"); return 202; }
Then, get the method ID in the `main' function of the C or C++ program. The following lines can be put near the similar declarations and calls to functions for the |ControlDetail| class or the |jobject jobjDet| object, respectively. jmethodID mid_CtrlDet_test_func = NULL; /* |ControlDetail::test_func| */ mid_CtrlDet_test_func = env->GetMethodID(clsC, "test_func", "()I"); jint i = env->CallIntMethod(jobjDet, mid_CtrlDet_test_func); cerr << "Return value of `mid_CtrlDet_test_func' is " << i << endl; /* Using C++ stream output here */ Thanks again for your very helpful example, Ahmad. Laurence
|
|
|
|
|
 |
> Should I create a header file and a .so file linking > Java and C libraries to run this? No, you don't need to create a header file, nor is there any need to create a shared library (.so) file. The first message says that the function `JNI_CreateJavaVM' is undefined. This probably means you're not linking with the library that contains the definition (presumably `libjvm'). It may be located in another place than on my system. Just have a look around and/or use `find' (look for `libjvm*.so'). Linking with an object file created from FORTRAN code shouldn't be too difficult. You just need to compile it separately from the C program and declare function in the latter, specifying "FORTRAN" linkage, i.e., including "Fortran" or "FORTRAN" in the declaration. I've never actually done this, but only read how to do it, and I don't remember the exact syntax. A quick search in the internet or the GCC manual should tell you how to do this. Then, link the object files. In the example I gave, I compiled and linked in one step, but it's not any more difficult to compile and link in two steps. The `-I' and `-L' options are needed for compiling and the `-l' option for linking. > CTest.o eh_frame+0x12): undefined reference to > `__gxx_personality_v0' I don't know what this is about. I believe it has something to do with the fact that GCC is used to compile various languages, so one back-end has various "personalities", i.e., one for FORTRAN, one for Pascal, etc. gxx is for C++. C++ is a bit different, because a C++ compiler (and linker) must do considerably more compilicated things than a compiler and linker for C, Fortran or Pascal. Are you sure gxx is installed? Does it work to compile a trivial C++ program? Otherwise, it's possible that this error might have something to do with the first one, and if you correct that one, this error might disappear. Otherwise, I'd try searching the internet to see if this error has been discussed somewhere. I hope this helps. Laurence
|
|
|
|
 |
CTest.o eh_frame+0x12): undefined reference to `__gxx_personality_v0' collect2: ld returned 1 exit status It just occurred to me that I've had a similar error message when the compiler couldn't tell from the extension of the filename whether it was C or C++. In this case, I would expect it to recognize that `.cpp' should be C++, but it wouldn't do any harm to change it to `.cxx' or use the `-x <language>' option, i.e., `-x c++'. Laurence
|
|
|
|
 |
Your article gave me some ideas to fix my code, which I was struggling with for several hours already.
|
|
|
|
 |
i have build a c++ dll via visual studio 2005, which i call by a jar-file and it works perfect on my computer also having the files on a usb-stick.
i tried several other computers and usually i get the message " main class not found ", which i suppose happens because the loading of the dll fails.
I´m not a professional programmer, but i´m quite sure the problem is connected with visual studio. the only other maschine my jar and dll worked was also equipped with visual studio.
there are loads of settings in the vc-project properties, which are hard for me to understand.
does anyone know, what is the problem and help me out.
|
|
|
|
 |
sorry, this was trivial. i just had to run the code in vs in release and not in debug mode.
|
|
|
|
 |
I have resolved all errors by adding addition library & include files.
Application is compiling without errors but after execution it crashes while
making a call to JNI_CreateJavaVM function.
Please help me on urgent basis.
|
|
|
|
 |
Could you please post the details of version of JDK and your working environment.
Also post the changes you made in the code.
Regards,
Qarshi
|
|
|
|
 |
I placed my exe in same directory where jvm.dll is (C:\Program Files\Java\jdk1.6.0\jre\bin\client), now it is working.Y it is not working when i put the jvm.dll in my debug folder.?
Can u please also guide me how can i call my class & methods from .jar file.
|
|
|
|
 |
Please add the jvm.dll file path in your environment variable (i.e. PATH ).
The reason now its working is because it found the jvm.dll file in the working folder.
All the executables (On Windows) search for some required library in following order:
The directory from which the application loaded. i.e. the Working folder.
The system directory.
The Windows directory.
The directories that are listed in the PATH environment variable.
As far as calling the class methods from a .jar method is concerned, yes you can. I haven't tried it personally but I am sure you can.
After making a .jar file execute the following command to see the contents of the jar file. Now while calling the FindClass function pass the path found the contents of following command:
jar tvf MyJar.jar
Suppose the path found for your class in the above jar file is "org/MyLibs/MyClass.class"
When you will be calling a FindClass function do as below:
(*env)->FindClass("org/MyLibs/MyClass");
I haven't tested it because I don't have any C compiler on my machine. So hopefully it will help.
Regards,
Ahmad Qarshi
|
|
|
|
 |
Thankyou for all of your support.
We have a method in our java class with following signature
void SomeMethod(int systemId,set < java.io.file > files,int prefPos)
Can u please guide us how can we pass set < java.io.file > files parameter from c++ to java method.modified on Wednesday, February 24, 2010 8:42 AM
|
|
|
|
 |
Hi,
I tried with this example, But i am getting same issue. If i copy C exe in JDK Folder it works else it raise Exception JVM initilisation error.
I read the above thread and try setting environment veriables but same results.
Can you please help me out in understanding the
The directory from which the application loaded. i.e. the Working folder.
The system directory.
The Windows directory.
The directories that are listed in the PATH environment variable.
Where and what need to set.
I am using Visual studio 2005 VC++ Compiler professional edition.
Saurabh Vashistha
|
|
|
|
 |
hi friend,
I am facing problem to call Java method from C++ project.
JNIEnv *env; JavaVMInitArgs vm_args; JavaVMOption options; options.optionString = "-Djava.class.path=D:\\Java Src\\TestStruct"; vm_args.version = JNI_VERSION_1_6; vm_args.nOptions = 1; vm_args.options = &options; vm_args.ignoreUnrecognized = 0; int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args); ///////Stop from here when running C++ proj.... what to do ??? if(ret < 0) printf("\nUnable to Launch JVM\n"); return env;
Need help...... plz
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
Type | Article |
Licence | CPOL |
First Posted | 12 Jan 2008 |
Views | 176,177 |
Downloads | 5,020 |
Bookmarked | 39 times |
|
|