问题描述
错误:
不会在运行 1 时发生,但在任何后续运行中,Python 内核都会死掉并且必须重新启动:
JNI_CreateJavaVM() Failed with result: -5
[SpyderKernelApp] WARNING | No such comm: aa125bd78d0711ebb9a2001a7dda7113
环境:
- 截至 2021 年 3 月的所有当前
- Win64
- Anaconda(实际上是迷你蟒蛇)
- Win64 的 Java 运行时
- Saxon/C(为 Win64 编译)1.2.1 与 Saxonica 的 Saxon-HE 9.9.1.5C 一起运行
测试脚本
这些 Saxon/c 提供的测试脚本产生相同的行为。运行OK一次但在第二次运行时导致 python 内核崩溃:
- saxon_example.py
- saxon_example2.py
- saxon_example3.py
猜测?
在交叉编译、cython、C++、JNI 等方面没有深入的经验。
也许第一个这样的 JNI 请求在 Windows 上加载 JavaVM 并且它保持运行。 (...它最终如何知道退出?)通过 JNI 的后续请求不会发送到正确的内存位置,即 “警告 | 没有这样的通信:aa125bd78d0711ebb9a2001a7dda7113”?指针问题?
尝试 1 删除了所有先前版本的 Java 运行时 (win64)。重新安装最新的 Java 运行时。没有变化。
更新 2
安德鲁,感谢您提供信息。
我发现这种情况有几个“层次”。我试图从 Python 运行的库是 saxon/c。 Saxon 最初是 Java,使用 Excelsior JET Enterprise 15.3 MP1 (10/2019) 编译为目标代码(与 Win64 兼容)。其他部分在 C 和 C++ 中使用 Windows Visual C++ 编译器编译。最后在构建过程中也使用了 cpython。
很确定传统的 Java 运行时(不需要运行典型的 JAR 文件,因为 Excelsior 会产生目标代码?我认为 Excelsior JET Enterprise 确实为其 Java 编译器提供了一些辅助目标代码,与 Visual C++ 要求的非常相似运行时间。所以我不确定 JNI 代码是如何合并的?
给情况增添了一些“迷雾”——总部位于俄罗斯的 Excelsior 退出,Java 编译器业务,取消了所有支持,据报道卖给了中国电信公司华为,华为迅速删除了 Excelsior 网站的所有痕迹。 (编不下去了!)
python 脚本运行一次正常,但在第二次运行时,它们使 python 内核崩溃,并出现 JNI 通信错误。以某种方式重新启动 python 内核修复了问题,但所有试图摆脱 saxonc.PySaxonProcessor 对象的尝试都无效。
import saxonc
with saxonc.PySaxonProcessor(license=False) as proc:
print(dir(proc)) #shows proc is running
proc.release()
proc=None
del proc
'''
解决方法
每 Java's Chapter 5: The Invocation API DestroyJavaVM()
documentation(我的粗体):
销毁JavaVM
jint DestroyJavaVM(JavaVM *vm);
卸载 Java VM 并回收其资源。
任何线程,无论是否附加,都可以调用此函数。如果 当前线程已附加,VM 等待直到当前线程 唯一的非守护程序用户级 Java 线程。如果当前线程是 未附加,VM 附加当前线程,然后等待直到 当前线程是唯一的非守护程序用户级线程。
链接:
JavaVM 接口函数表中的索引 3。
参数:
vm:将被销毁的 Java VM。
退货:
成功返回JNI_OK;返回一个合适的 JNI 错误代码(a 负数)失败。
不支持卸载 VM。
注意最后一个:
不支持卸载虚拟机。
您只能在一个进程中创建一个 JVM 实例。曾经。