首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jpype简单jar导入并运行main()

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

Stack Overflow用户
提问于 2019-04-16 22:33:34
回答 2查看 4.2K关注 0票数 3

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

代码语言:javascript
复制
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()

我得到了这个错误: TypeError: Package phylonet.coalescent.CommandLine.main是不可调用的

我提供了jar文件的绝对路径,并从main /MANIFEST.MF获得了主要功能:

代码语言:javascript
复制
cat tmp/META-INF/MANIFEST.MF | grep Main-Class
Main-Class: phylonet.coalescent.CommandLine

我试图打开的jar文件名为astral,从这里:https://github.com/smirarab/ASTRAL

像这样调用它就像预期的那样工作:

代码语言:javascript
复制
java -Djava.class.path="./astral.jar"

所以为什么我用jpype来称呼它呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-03 20:08:24

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

代码语言:javascript
复制
TypeError: Package clip.frontend.Start.main is not Callable

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

代码语言:javascript
复制
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()

输出是正确的:

代码语言:javascript
复制
% python2 main.py
2 2
+>+[<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>+<<<<<<<<<[-]>[-]>>>>>>>>[<<<<<<<<+>+>>>>>>>-]
<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[-]<<<<<<]<<<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>++
[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>[>>]+<<[<<]>[>[>>]
<+<[<<]>-]<<<<<<<[-]++[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>
[>>]+<<[<<]>[>[>>]<+<[<<]>-]<<<<<<<[-]#JVM has been shutdown

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

代码语言:javascript
复制
import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JClass("phylonet.coalescent.CommandLine").main([])
jpype.shutdownJVM()

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

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

代码语言:javascript
复制
import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JPackage('phylonet').coalescent.CommandLine.main([])
jpype.shutdownJVM()

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

代码语言:javascript
复制
'-Djava.class.path="%s"' % jar

事实上,我用它来反对我的答案,然后,代码会产生这样的结果:

代码语言:javascript
复制
TypeError: Package phylonet.coalescent.CommandLine.main is not Callable

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

代码语言:javascript
复制
-Djava.class.path="astral.jar"

而不是跟随

代码语言:javascript
复制
-Djava.class.path=astral.jar

引号放错了位置,结果引起了错误。

票数 6
EN

Stack Overflow用户

发布于 2019-06-14 03:58:39

这是JPype的经典问题。如果无法加载jar,那么JPackage将返回另一个不可调用的JPackage。加载失败的常见原因包括

  • 加载的JVM不支持jar的版本(请检查getDefaultJVMPath()是不是旧版本)
  • 缺少一个jar依赖项。
  • JVM无法找到Jar作为指定的路径。

前面的解决方案是使用java.lang.Class.forName,它将在jar加载时打印诊断信息。目前作为发布候选版本的0.7.0版本已经解决了这一问题。

此外,在导入类时,建议您使用jpype.importsJClass而不是JPackage。它更安全,因为它将报告一个更有意义的错误。例如:

代码语言:javascript
复制
import jpype
import jpype.imports

jpype.startJVM()
jpype.imports.registerDomain('phylonet')  # This is required as phylonet is not a tld

from phylonet.coalescent import CommandLine

您可以将包标记为符合标准(类从上面开始,包较低),以强制错误。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55717482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档