jpype 简单的 jar 导入并运行 main()

Dav*_*der 3 python java jpype

我正在尝试打开一个 jar 文件并执行它的主要功能,但是 jpype 抛出了一个对我来说没有意义的错误。这是我的代码:

jpype.startJVM(jpype.getDefaultJVMPath(), '-Djava.class.path="%s"' % jar)
CommandLine = jpype.JPackage('phylonet').coalescent.CommandLine
CommandLine.main(['-i', input_file, '-o', output_file])
jpype.shutdownJVM()
Run Code Online (Sandbox Code Playgroud)

我收到此错误:TypeError: Package phylonet.coalescent.CommandLine.main is not Callable

我已经提供了 jar 文件的绝对路径,并且我已经从 META-INF/MANIFEST.MF 获得了主要功能:

cat tmp/META-INF/MANIFEST.MF | grep Main-Class
Main-Class: phylonet.coalescent.CommandLine
Run Code Online (Sandbox Code Playgroud)

我试图打开的 jar 文件叫做 astral,来自这里:https : //github.com/smirarab/ASTRAL

像这样调用它按预期工作:

java -Djava.class.path="./astral.jar"
Run Code Online (Sandbox Code Playgroud)

那么当我用 jpype 调用它时为什么不呢?

Krz*_*zyk 6

首先,我已经在我自己的 jarfile 上测试了你的代码。确实,我遇到了这样的错误:

TypeError: Package clip.frontend.Start.main is not Callable
Run Code Online (Sandbox Code Playgroud)

然后,在仔细阅读文档后,我使用了另一种方法。

import jpype

# I've used other set of parameters to JVM, and modified a bit your classpath setting.
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=clip.jar")

# Second difference, I decided to use JClass because it was more clear for me.
# Parameter array was kept empty.
jpype.JClass("clip.frontend.Start").main([])
jpype.shutdownJVM()
Run Code Online (Sandbox Code Playgroud)

输出是正确的:

% python2 main.py
2 2
+>+[<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>+<<<<<<<<<[-]>[-]>>>>>>>>[<<<<<<<<+>+>>>>>>>-]
<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[-]<<<<<<]<<<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>++
[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>[>>]+<<[<<]>[>[>>]
<+<[<<]>-]<<<<<<<[-]++[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>
[>>]+<<[<<]>[>[>>]<+<[<<]>-]<<<<<<<[-]#JVM has been shutdown
Run Code Online (Sandbox Code Playgroud)

现在,我决定翻译我的解决方案以匹配您的问题:

% python2 main.py
2 2
+>+[<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>+<<<<<<<<<[-]>[-]>>>>>>>>[<<<<<<<<+>+>>>>>>>-]
<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[-]<<<<<<]<<<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>++
[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>[>>]+<<[<<]>[>[>>]
<+<[<<]>-]<<<<<<<[-]++[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>
[>>]+<<[<<]>[>[>>]<+<[<<]>-]<<<<<<<[-]#JVM has been shutdown
Run Code Online (Sandbox Code Playgroud)

并且代码工作正常。比实际解决方案更重要的是,为什么您的代码不起作用。您使用了错误的参数集并以一种方式指定了类路径。

用 JPackage 替换 JClass,代码仍然有效。

import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JClass("phylonet.coalescent.CommandLine").main([])
jpype.shutdownJVM()
Run Code Online (Sandbox Code Playgroud)

由于从类路径中提取类的方式是正确的,唯一可能的原因是指定了无效的参数集。去掉-ea代码后仍然有效,所以你犯的错误就在这段代码中。

import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JPackage('phylonet').coalescent.CommandLine.main([])
jpype.shutdownJVM()
Run Code Online (Sandbox Code Playgroud)

事实上,我已经用这个来反对我的答案了,砰,代码产生了这个:

'-Djava.class.path="%s"' % jar
Run Code Online (Sandbox Code Playgroud)

这意味着,该参数包含以下内容:

-Djava.class.path="astral.jar"
Run Code Online (Sandbox Code Playgroud)

而不是跟随

-Djava.class.path=astral.jar
Run Code Online (Sandbox Code Playgroud)

引号放错了位置并引发了结果错误。