JNI, call java from C++.

T

tony_lincoln

Dear friends,


I am using JNI to call java from C++. I use j2sdk1.4.1 and Visual C++
6.

If my Java source code is like this:
******************************­**************************
import com.tony.package1.classA;
....
public static void main(String[] args) {
System.out.println("This is a test");
}// end main()
....
******************************­***************************
It will work and C++ can call java successfully. But if the Java code
is the following:

******************************­**************************
import com.tony.package1.classA;
....
public static void main(String[] args) {
System.out.println("This is a test");
String [] str = new classA.method1();
System.out.println(str[0]);
}
....
******************************­***************************

When I invoke this java class from C++ codes in Visual C++, the "This
is a test" can be shown in DOS shell, then it shows:
" An unexpected error has been detected by HotSpot Virtual Machine:
Internal Error (57437914380392184392743120947­000FF),
pid = 3288, tid = 3292.
...."

I am sure that classA was written and compiled in correct way, so the
error is not about it. The error should be something about the path and
package.
E:\codes_Tony is in my classpath, and com.tony.package1.ClassA
is in E:\codes_Tony\com\tony\package1.
Is there anything wrong about the path? Any hints?
THanks a lot.
Tony
 
G

Gordon Beaton

When I invoke this java class from C++ codes in Visual C++, the "This
is a test" can be shown in DOS shell, then it shows:
" An unexpected error has been detected by HotSpot Virtual Machine:
Internal Error (57437914380392184392743120947­000FF),
pid = 3288, tid = 3292.
..."

Quite simply, there is an error in your code. Read my latest response
to your nearly identical question in the other thread where you
initially brought this up. Please don't start new threads unless
you've got new issues!

/gordon
 
T

tony_lincoln

I do not think that there is errors in my source code. I made a test
and the source code is following:
DemoMain.java is the java code invoked by C++ code. IOTest.class is the
java class used by DemoMain.

DemoMain.java
******************************************************************************************************
import com.tony.jniClasses.IOTest;
import java.io.*;

public class DemoMain {
public static void main(String[] args)
throws java.io.IOException, java.lang.NullPointerException
{
System.out.println("This is a test.");
IOTest.printLines();
}// end main().
}// end class DemoMain.
**************************************************************************************************************************


IOTest.java
**************************************************************************************************************************
package com.tony.jniClasses;
import java.io.*;

public class IOTest
{
public static void printLines()
{
System.out.println("Line 1: no input, no output");
System.out.println("Line 2: no input, no output");
}// end printLines()
}// end class IOTest.
*****************************************************************************************************************

When I run the c++ code under Visual C++ studio 6.0,
the "This is a test" can be shown in DOS shell, then it shows:
" An unexpected error has been detected by HotSpot Virtual Machine:
Internal Error (57437914380392184392743120947­000FF),
pid = 3288, tid = 3292.
...."

What is error ????? Any hints?
TOny
 
A

Andoni

I do not think that there is errors in my source code. I made a test
and the source code is following:

Unfortunately the code doesn't care whether you think there is an error or
not!
DemoMain.java is the java code invoked by C++ code. IOTest.class is the
java class used by DemoMain.

This code does not have the error.
What is error ????? Any hints?

That's the attitude. The error in here:

String [] str = new classA.method1();

You need more brackets. What you are saying is effectively:
String [] str = new (classA.method1());

Which will give you an error. What you should be saying is:

String [] str = (new classA).method1();

Hope that helps,

Andoni.
 
T

tony_lincoln

Thanks for the analysis. I am not sure if you are correct, but I know
that this error is caused by CallStaticVoidMethod() in C++ codes. What
I have done to prove this is:
I simplied the C++ codes and Java codes, as following:

/*for C++,debugged with Visual C++ 6.0*/
// invoke.cpp

#ifndef __cplusplus
#define __cplusplus
#endif

#include "jni.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#pragma comment (lib,"E:\\Programme\\Java\\jdk1.5.0_02\\lib\\jvm.lib")

void main() {

JavaVM *jvm;
JNIEnv *env;

JavaVMInitArgs vm_args;
JavaVMOption options[3];

options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.classpath=.";
options[2].optionString = "-verbose:jni";

vm_args.version = JNI_VERSION_1_4;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;

jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
exit(1);
};

jclass cls = env->FindClass("DemoMain");
if (cls == 0) printf("Sorry, I can't find the class");

jmethodID get_main_id;

if(cls != NULL)
{
get_main_id =
env->GetStaticMethodID(cls,"main","([Ljava/lang/String;)V");

if(get_main_id != NULL )
{
jclass string = env->FindClass("java/lang/String");
jobjectArray args = env->NewObjectArray(0,string, NULL);

fprintf(stdout, "This is invokeSimplified6.\n");
env->CallStaticVoidMethod(cls, get_main_id, args);
fprintf(stdout, "This is invokeSimplified7.\n");

}// end IF.

}// end IF.


jvm->DestroyJavaVM();
fprintf(stdout, "Java VM destory\n");
}//end main.

**************************************************************************************************************

In the main() of Java codes DemoMain.java, there are only 2 sentences:
System.out.println ("This is a test");
IOTest.print2Lines();

IOTest is another java class located in a different directory. There
are only 2 sentences in print2Lines():
System.out.println ("Line1");
System.out.println ("Line2");

I simply these classes, so no parameter was transmitted in different
methods or classes.
I run the c++ codes, the output is like this:
________________________________________________________________________________
....
This is invokeSimplified6.
[Dynamic-linking native method java.io.FileOutputStream.writeBytes ...
JNI]
This is a test.
This is invokeSimplified7.
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# Internal Error (455843455054494F4E530E43505000FF), pid=3704,
tid=4064
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_02-b09 interpreted mode,
sharing)
# An error report file with more information is saved as
hs_err_pid3704.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
---------------------------------------------------------------------------------------------------------------------------------

So I know that this error is caused by CallStaticVoidMethod(). But how
to change it so the output is correct?
Thanks a lot.
tony
 
G

Gordon Beaton

Thanks for the analysis. I am not sure if you are correct, but I
know that this error is caused by CallStaticVoidMethod() in C++
codes. What I have done to prove this is:

First, main() always returns int, never void.

Second, it's a good idea to use fprintf(stderr, ...) for your error
messages or you risk missing the last ones prior to the crash due to
buffering.

What happens if you don't use DestroyJavaVM() at the end of the
program, or don't call CallStaticVoidMethod()?
So I know that this error is caused by CallStaticVoidMethod().

But the text line *following* CallStaticVoidMethod() is displayed!

/gordon
 
T

tony_lincoln

(1)
Which main()? In DemoMain.java or in C++ codes? if in DemoMain(), I
tried this, I do not call CallStaticVoidMethod(), but error appeared:
*************************************error********************************************************************************
[Dynamic-linking native method java.lang.ClassLoader.defineClass1 ...
JNI]
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# Internal Error (455843455054494F4E530E43505000FF), pid=3080,
tid=3132
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_02-b09 interpreted mode,
sharing)
# An error report file with more information is saved as
hs_err_pid3080.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
Press any key to continue
*****************************************end of
error***************************************************

(2)
If I do not call CallStaticVoidMethod(), there will be no error when I
executed the c++ codes! So I doubt there is one error in this method,
or I should not use this method!

If I don't use DestroyJavaVM(), there are 2 cases:
a. I do not call CallStaticVoidMethod(), then the C++ codes work and
the result is:
__________________________
This is invokeSimplified6.
This is invokeSimplified7.
Press any key to continue
-------------------------------------------
b. if I call CallStaticVoidMethod(), then the result is:
__________________________________
This is invokeSimplified6.
[Dynamic-linking native method java.io.FileOutputStream.writeBytes ...
JNI]
This is a test.
This is invokeSimplified7.
Java VM destory
Press any key to continue
------------------------------------------------------------

The method IOTest.print2Lines() is still not called. How to call this
method?
Thanks.
tony
 
T

tony_lincoln

if the return of DemoMain() is int, for example, then the C++ codes
were changed like this:

________________________________________________________________________________
jclass cls = env->FindClass("DemoMain");
if (cls == 0) printf("Sorry, I can't find the class");

fprintf(stdout, "This is invokeSimplified4.\n");

jmethodID get_main_id;

if(cls != NULL)
{
get_main_id =
env->GetStaticMethodID(cls,"main","([Ljava/lang/String;)V");
fprintf(stdout, "This is invokeSimplified5.\n");

if(get_main_id != NULL )
{
jclass string = env->FindClass("java/lang/String");
jobjectArray args = env->NewObjectArray(0,string, NULL);

fprintf(stdout, "This is invokeSimplified6.\n");
int i = env->CallIntMethod(cls, get_main_id, args);
fprintf(stdout, i+ "This is invokeSimplified7.\n");

}// end IF.

}// end IF.
_______________________________________________________________________

Then the output will be:

"This is invokeSimplified4.
This is invokeSimplified5.
Java VM destory
Press any key to continue"

This means, the get_main_id is NULL. So l wonder if the return of
Main() in java code should be void.
Best wishes.
tony
 
G

Gordon Beaton

This means, the get_main_id is NULL. So l wonder if the return of
Main() in java code should be void.

main() in Java always returns void.

main() in C and C++ always returns int.

/gordon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,999
Latest member
MakersCBDGummiesReview

Latest Threads

Top