Jpype导入在JAR中找不到模块

人气:149 发布:2023-01-03 标签: python java import executable-jar jpype

问题描述

我在工作中收到了一项任务,要找到一种方法来使用一个Python项目中现有JAR文件中的一些方法。我在Python方面的经验非常有限,但我以前使用过那个特定的JAR文件(它是我们正在进行的一个项目的一部分)。我不允许修改这两个项目的大部分内容,并且要求它们尽可能独立。

我研究了在Python中包含JAR方法的多种方法。到目前为止,我已经尝试了Jython(我不能使用它,因为在其他库中,我不能使用PyQt,如果我的理解正确的话,这些库强制使用CPython)、Pyjnius和JPype。JPype似乎是最有前途的,但我也无法让它正常工作。我粘贴了下面的代码,略有删节,因为我不知道允许我分享多少内容。

from jpype import *
import jpype.imports

try:
    jpype.addClassPath("jars/sdk.jar") #the relative path to the jar file
    jpype.startJVM(convertStrings=False)
    java.lang.System.out.println(jpype.getClassPath()) #printing the classpath to check, the path is correctly pointing to the sdk.jar file

    java.lang.System.out.println("Hello world") #just to check if jpype is installed correctly, works

    jpype.imports.registerDomain("a")
    from a.b.c.d.e.f.g.h import SomeClass #fails here

except OSError as err:
    print(err)  # ToDo: Remove print when done
    pass
我收到的错误是找不到模块a.b.c.d.e.f.g.h.SomeClass。我尝试了不同的方法来指定路径(绝对路径、相对路径、将JAR放在项目中的不同位置和项目外),但这似乎不是问题所在,因为打印的路径是指向JAR文件的正确绝对路径。

此外,JAR还在其他(Java)项目中使用,并且可以正常工作。它是使用maven包创建的(如果相关,则使用IntelliJ,并且与JPype JVM使用的Java版本相同)。在Java项目中,导入将是:

import a.b.c.d.e.f.g.h.SomeClass;

我已经复制了这段代码,并将其语法转换为Python。

我还尝试使用JObject创建类(我可能无论如何都做得不对),还尝试了使用JPackage使用较旧的语法(据我所知)。对于JPackage方式,我得到了一个异常,即包a.b.c.d.e.f.g.h.SomeClass.omeMethod是不可调用的,据我所知,这是一个与我使用jpype导入得到的包等价的异常。我已经检查了我在这里找到的具有类似问题的所有问题,但这些解决方案都没有帮助我。

有人能提出一些可能的解决方案吗?或者有人看得出我做错了什么?其他替代JPype的可能性的建议也受到欢迎。如果需要澄清,我将编辑问题。

推荐答案

如果JAR位于类路径上并且导入失败,则唯一可能发生的情况是缺少一些依赖项。您还有另外两种方法可以尝试加载类,这可能会提供其他诊断。

jpype.JClass("a.b.c.d.e.f.g.h.SomeClass")

jpype.JClass("java.lang.Class").forName("a.b.c.d.e.f.g.h.SomeClass")

第一种是按照完整的类规范手动加载类。从机械上讲,这是进口下正在发生的事情。第二个是调用Java来加载类(绕过所有的JPype)。它返回一个java.lang.Class,可以将其传递给JClass以生成包装。

常见故障包括缺少JAR或本机库、尝试从模块内启动JPype并具有错误的相对路径、由于缺少资源而导致类的初始化错误。JPype只是调用JNI调用,所以如果Java End上一切正常,它应该可以工作。假设您检查了java.class.Path系统变量,那么它一定与类资源有关。

JPype用户手册中有一个备选方案部分,如果您想要尝试查找其他包。除了PyJnius之外,大多数替代方案似乎都没有得到维护。

15