Dynamic loading of jvm library into go code on windows

1

I am working on loading jvm.dll into go programm using cgo bindings on windows(GOOS=windows;GOARCH=amd64). JDK is installed and following is configured in PATH variable:

  • c:\Program Files\Java\jdk1.8.0_231\bin\
  • c:\Program Files\Java\jdk1.8.0_231\jre\bin\server\
  • c:\Program Files\Java\jdk1.8.0_231\jre\bin\

    %_ALT_JAVA_HOME_DIR% is set to "c:\Program Files\Java\jdk1.8.0_231\jre\"

C code below:

JVM *jvm;
jvm = malloc(sizeof(JVM));
JavaVMInitArgs vm_args;
vm_args.version=JNI_VERSION_1_8;
jint ret = JNI_CreateJavaVM(&jvm->jvm, (void **)&jvm->env, &vm_args);

}

is calling go code below

import "C"
import (
    "syscall"
    "unsafe"
)

var mod, _ = syscall.LoadLibrary("jvm.dll")
var createJvm, _ = syscall.GetProcAddress(mod, "JNI_CreateJavaVM")
var getDefaultArgs,_ = syscall.GetProcAddress(mod, "JNI_GetDefaultJavaVMInitArgs")

//export JNI_CreateJavaVM
func JNI_CreateJavaVM(jvm unsafe.Pointer, env unsafe.Pointer, args unsafe.Pointer) int32 {
    println("jvm", jvm)
    println("env", env)
    println("args", args)
    var resCode, _, err = syscall.Syscall(uintptr(getDefaultArgs), 1, uintptr(args),0,0);
    println("result of JNI_GetDefaultJavaVMInitArgs",  int32( resCode),  err)
    resCode, _, err = syscall.Syscall(uintptr(createJvm), 3, uintptr(jvm), uintptr(env), uintptr(args));
    println("result of JNI_CreateJavaVM", int32( resCode),  err)
    return int32(resCode);
}

At second syscall code fails with following output:

env 0xe05de0
args 0x86fcf0
result of JNI_GetDefaultJavaVMInitArgs 0 0
Exception 0xc0000005 0x0 0x0 0x286503b6
PC=0x286503b6
signal arrived during external code execution

syscall.Syscall(0x6caae840, 0x3, 0xe05de8, 0xe05de0, 0x86fcf0, 0x0, 0x0, 0x0)
    C:/Users/user/sdk/go1.14rc1/src/runtime/syscall_windows.go:188 +0xe9
test/jni.JNI_CreateJavaVM(0xe05de8, 0xe05de0, 0x86fcf0, 0x0)
    C:/Users/user/IdeaProjects/test/jni/jni.go:21 +0x1c1
test/jni._cgoexpwrap_c7fe4a664520_JNI_CreateJavaVM(0xe05de8, 0xe05de0, 0x86fcf0, 0x7ffada619da0)
    _cgo_gotypes.go:467 +0x46
test/jni._Cfunc_createJVM(0xe01a50, 0x6, 0x0)
    _cgo_gotypes.go:407 +0x55
test/jni.CreateJVM.func3(0xe01a50, 0xc000035f18, 0x6, 0x6, 0xc000004280)
    C:/Users/user/IdeaProjects/test/jni/jvm.go:41 +0x5d
test/jni.CreateJVM(0xc000035f18, 0x6, 0x6, 0x0)
    C:/Users/user/IdeaProjects/test/jni/jvm.go:41 +0x14e
main.main()
    C:/Users/user/IdeaProjects/test/main.go:16 +0xf3
rax     0x6
rbx     0x100800
rcx     0xcafebabe
rdi     0x1
rsi     0x0
rbp     0x6d16f550
rsp     0x86f258
r8      0x2865047b
r9      0x86f420
r10     0x2
r11     0x86f590
r12     0x3d8
r13     0x0
r14     0x0
r15     0x2030000
rip     0x286503b6
rflags  0x210246
cs      0x33
fs      0x53
gs      0x2b

I checked and confirmed that jvm.dll is loaded, both symbols are available, call to JNI_GetDefaultJavaVMInitArgs is successful. Any ideas where to look into and what is wrong with the call to JNI_CreateJavaVM?

c
go
jvm
java-native-interface
asked on Stack Overflow Feb 23, 2020 by Eugene • edited Feb 23, 2020 by Eugene

1 Answer

0

OK, such a behavior is caused by https://github.com/golang/go/issues/20498. In order to bypass the error go source code needs to be adjusted: src/runtime/signal_windows.go#127 should be changed from var testingWER bool to var testingWER=true

answered on Stack Overflow Nov 5, 2020 by Eugene

User contributions licensed under CC BY-SA 3.0