【问题标题】:Dynamic loading of jvm library into go code on windows将 jvm 库动态加载到 windows 上的 go 代码中
【发布时间】:2020-02-23 15:32:12
【问题描述】:

我正在使用 windows (GOOS=windows;GOARCH=amd64) 上的 cgo 绑定将 jvm.dll 加载到 go 程序中。 JDK 已安装并在 PATH 变量中配置以下内容:

  • 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% 设置为“c:\Program Files\Java\jdk1.8.0_231\jre\”

C 代码如下:

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

}

在下面调用go代码

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);
}

第二次系统调用代码失败,输出如下:

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

我检查并确认 jvm.dll 已加载,两个符号都可用,对 JNI_GetDefaultJavaVMInitArgs 的调用成功。 对 JNI_CreateJavaVM 的调用有什么想法吗?

【问题讨论】:

  • 看起来第 8 版的问题与缺少符号 ZIP_ReadMappedEntry 有关。尝试加载已在 JDK-8166930 中修复的 zip.dll 后观察到的失败:小清理 1) 删除对 ZIP_ReadMappedEntry 2 的引用) 检查 st_mode
  • 切换到最新的 jdk13。相同的代码,添加了 -Xlog:all=trace。日志在 [0.009s][info][aot,startuptime] AOT 初始化时停止,0.0003837 秒。加载 jimage.dll 时失败。有什么建议吗?

标签: c go jvm java-native-interface


【解决方案1】:

好的,这样的行为是由https://github.com/golang/go/issues/20498引起的。为了绕过错误,需要对源代码进行调整: src/runtime/signal_windows.go#127 应该从 var testingWER bool 到 var testingWER=true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多