jpype.startjvm 退出而不给出任何错误消息

Posted

技术标签:

【中文标题】jpype.startjvm 退出而不给出任何错误消息【英文标题】:jpype.startjvm exits without giving any error message 【发布时间】:2021-11-03 10:08:12 【问题描述】:

我正在尝试使用Python MPXJ 来分析来自 mpp 文件的信息。在我的 Windows 10 机器中,我安装了 32 位 Python 3.8.0,并由 pip install jpype1 准备了 JPYPE。我也在C:\Program Files (x86)\Java\jre1.8.0_301中安装JRE 32bit。

但是,下面的脚本完全失败了

import jpype

print(jpype.getDefaultJVMPath())
jpype.startJVM()
print("JVM successfully started")
jpype.shutdownJVM()

它显示默认路径为C:\Program Files (x86)\Java\jre1.8.0_301\bin\client\jvm.dll,但是下一个打印行没有执行,startJVM 也没有给出任何错误输出。执行结果如下

> python testjvm.py
C:\Program Files (x86)\Java\jre1.8.0_301\bin\client\jvm.dll

所以startJVM 被执行,但没有给出任何东西就退出。

有没有办法进一步调试可能是什么问题?


根据 John 的建议,我正在使用 ipython 进行进一步调试。它使用以下上下文转到c:\python38\lib\site-packages\jpype\_core.py(226)

> c:\python38\lib\site-packages\jpype\_core.py(225)startJVM()
    223                         % (','.join([str(i) for i in kwargs])))
    224
3-> 225     try:
    226         _jpype.startup(jvmpath, tuple(args),
    227                        ignoreUnrecognized, convertStrings, interrupt)

ipdb> jvmpath
'C:\\Program Files (x86)\\Java\\jre1.8.0_301\\bin\\client\\jvm.dll'
ipdb> args
args = []
kwargs = 
ipdb> tuple(args)
()
ipdb> ignoreUnrecognized
False
ipdb> convertStrings
False
ipdb> interrupt
False

那么无论我在_jpype.startup上按sn,ipython都没有任何提示退出

【问题讨论】:

@JohnHennig,我使用 ipython 进入startJVM。它转到lib\site-packages\jpype\_core.py(225),然后在执行_jpype.startup 时退出。我在原始帖子中添加详细信息。是否需要使用 32 位 Visual Studio 来编译 32 位 jpype?以前我使用相同的 Visual Studio 为 VIM 32bit 编译 youcompleteme pyc,它工作正常。 谢谢@JohnHennig,经过进一步调查,我发现即使安装了 java x86,也无法在 x64 窗口中使用 JPype 运行 python x86。我将在回答帖子中详细说明 【参考方案1】:

感谢 John Hennig 的评论,指出根本原因可能是 x86 和 x64 不兼容问题。

我根据JVM startup debugging 做了一些进一步的调试。基本上它使用Dumpbin 实用程序与Visual Studio 一起检查每个组件以查看它是x86 还是x64。如果其中任何一个不兼容,jvm start 将会崩溃。

原来我机器里的python.exejvm.dll都是x86的。但是,当使用where 定位依赖项时

    KERNEL32.dll
    USER32.dll
    ADVAPI32.dll
    WSOCK32.dll
    WINMM.dll
    VERSION.dll
    PSAPI.DLL
    VCRUNTIME140.dll
    api-ms-win-crt-stdio-l1-1-0.dll
    api-ms-win-crt-string-l1-1-0.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-convert-l1-1-0.dll
    api-ms-win-crt-environment-l1-1-0.dll
    api-ms-win-crt-utility-l1-1-0.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-filesystem-l1-1-0.dll
    api-ms-win-crt-time-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll

原来第一个dllKERNEL32.dll位于c:\Windows\System32,它是x64的。其他 dll 也是如此。由于它们是 x64 窗口中的系统默认 dll,因此用 x86 替换它们将非常棘手。因此在 x64 窗口中无法使用带有 JPype 的 python x86 版本。

解决方案很简单,将 python/java 更改为 x64 版本即可解决问题。

【讨论】:

以上是关于jpype.startjvm 退出而不给出任何错误消息的主要内容,如果未能解决你的问题,请参考以下文章

python调用jar包类

JObject 解析器停止执行而不给出任何输出或错误

<JAVA_HOME>/lib/ext 存在,不再支持扩展机制

UserManager 退出函数而不抛出任何异常

多处理程序(生产者-消费者)退出而不打印任何东西 Python 3

MySQL服务器启动错误'服务器退出而不更新PID文件'