I am currently getting this error message if I run the code using CGO. Using almost the same code in pure C, I don't get the error message.
Go (CGO) case: The code below will compile without errors but will give out an error when executed.
package main
/*
#cgo CFLAGS: -Id:/jdk/include -Id:/jdk/include/win32
#cgo LDFLAGS: -Ld:/jdk/jre/bin/server -ljvm
#include <jni.h>
JNIEnv* create_vm(JavaVM **jvm)
{
JNIEnv* env;
printf("*env
");
JavaVMInitArgs args;
printf("args
");
JavaVMOption options;
printf("options
");
args.version = JNI_VERSION_1_8;
args.nOptions = 0;
printf("set values
");
int rv;
rv = JNI_CreateJavaVM(jvm, (void**)&env, &args);
printf("jni create java vm
");
if (rv != JNI_OK) {
printf("Failed to create Java VMn");
} else {
printf("Launched JVM! :)
");
}
return env;
}
void invoke_class(JNIEnv* env)
{
jclass hello_world_class;
jmethodID main_method;
jmethodID square_method;
jmethodID power_method;
jint number=20;
jint exponent=3;
hello_world_class = (*env)->FindClass(env, "helloWorld");
main_method = (*env)->GetStaticMethodID(env, hello_world_class, "main", "([Ljava/lang/String;)V");
square_method = (*env)->GetStaticMethodID(env, hello_world_class, "square", "(I)I");
power_method = (*env)->GetStaticMethodID(env, hello_world_class, "power", "(II)I");
(*env)->CallStaticVoidMethod(env, hello_world_class, main_method, NULL);
printf("%d squared is %d
", number,
(*env)->CallStaticIntMethod(env, hello_world_class, square_method, number));
printf("%d raised to the %d power is %d
", number, exponent,
(*env)->CallStaticIntMethod(env, hello_world_class, power_method, number, exponent));
}
void test()
{
printf("START TEST
");
JavaVM *jvm;
printf("*jvm
");
JNIEnv *env;
printf("*env
");
env = create_vm(&jvm);
printf("create_vm
");
invoke_class(env);
printf("invoke class
");
}
*/
import "C"
func main() {
C.test()
}
Output of the CGO code above
START TEST
*jvm
*env
*env
args
options
set values
Exception 0xc0000005 0x0 0x0 0x50003b6
PC=0x50003b6
signal arrived during external code execution
main._Cfunc_test()
command-line-arguments/_obj/_cgo_gotypes.go:43 +0x48
main.main()
D:/Projects/Go/src/loable.tech/go-jasper/main.go:66 +0x27
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
D:/Go/src/runtime/asm_amd64.s:2197 +0x1
rax 0x6
rbx 0x3100800
rcx 0xcafebabe
rdi 0x1
rsi 0x0
rbp 0x51e052a0
rsp 0x72f678
r8 0x500047b
r9 0x72f840
r10 0x2
r11 0x72f9b0
r12 0x3d8
r13 0x6
r14 0x0
r15 0xf1
rip 0x50003b6
rflags 0x210246
cs 0x33
fs 0x53
gs 0x2b
Now here's the confusing part. When I use C instead of go and using almost the same code as above, everything works as expected.
Pure C code
#include <jni.h>
JNIEnv* create_vm(JavaVM **jvm)
{
JNIEnv* env;
printf("*env
");
JavaVMInitArgs args;
printf("args
");
JavaVMOption options;
printf("options
");
args.version = JNI_VERSION_1_8;
args.nOptions = 0;
printf("set values
");
int rv;
rv = JNI_CreateJavaVM(jvm, (void**)&env, &args);
printf("jni create java vm
");
if (rv != JNI_OK) {
printf("Failed to create Java VMn");
} else {
printf("Launched JVM! :)
");
}
return env;
}
void invoke_class(JNIEnv* env)
{
jclass hello_world_class;
jmethodID main_method;
jmethodID square_method;
jmethodID power_method;
jint number=20;
jint exponent=3;
hello_world_class = (*env)->FindClass(env, "helloWorld");
main_method = (*env)->GetStaticMethodID(env, hello_world_class, "main", "([Ljava/lang/String;)V");
square_method = (*env)->GetStaticMethodID(env, hello_world_class, "square", "(I)I");
power_method = (*env)->GetStaticMethodID(env, hello_world_class, "power", "(II)I");
(*env)->CallStaticVoidMethod(env, hello_world_class, main_method, NULL);
printf("%d squared is %d
", number,
(*env)->CallStaticIntMethod(env, hello_world_class, square_method, number));
printf("%d raised to the %d power is %d
", number, exponent,
(*env)->CallStaticIntMethod(env, hello_world_class, power_method, number, exponent));
}
void main()
{
printf("START TEST
");
JavaVM *jvm;
printf("*jvm
");
JNIEnv *env;
printf("*env
");
env = create_vm(&jvm);
printf("create_vm
");
invoke_class(env);
printf("invoke class
");
}
This is the output of the C code above, which is the output that I am expecting.
START TEST
*jvm
*env
*env
args
options
set values
jni create java vm
Launched JVM! :)
create_vm
Hello, World
20 squared is 400
20 raised to the 3 power is 8000
invoke class