jpype 简单 jar 导入和 运行 main()
jpype simple jar import and run main()
我试图打开一个 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()
我收到这个错误:
类型错误:包 phylonet.coalescent.CommandLine.main 不可调用
我已经提供了 jar 文件的绝对路径,并且我已经从 META-INF/MANIFEST.MF:
获得了主要功能
cat tmp/META-INF/MANIFEST.MF | grep Main-Class
Main-Class: phylonet.coalescent.CommandLine
我尝试打开的 jar 文件名为 astral,来自此处:https://github.com/smirarab/ASTRAL
按预期方式调用它:
java -Djava.class.path="./astral.jar"
为什么我用 jpype 调用它时不呢?
首先,我已经在我自己的 jarfile 上测试了你的代码。确实,我遇到了这样的错误:
TypeError: Package clip.frontend.Start.main is not Callable
然后,仔细阅读文档后,我使用了另一种方法。
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()
并且输出是正确的:
% python2 main.py
2 2
+>+[<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>+<<<<<<<<<[-]>[-]>>>>>>>>[<<<<<<<<+>+>>>>>>>-]
<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[-]<<<<<<]<<<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>++
[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>[>>]+<<[<<]>[>[>>]
<+<[<<]>-]<<<<<<<[-]++[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>
[>>]+<<[<<]>[>[>>]<+<[<<]>-]<<<<<<<[-]#JVM has been shutdown
现在,我决定翻译我的解决方案来匹配您的问题:
import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JClass("phylonet.coalescent.CommandLine").main([])
jpype.shutdownJVM()
代码运行正常。比实际解决方案更重要的是,为什么您的代码不起作用。您使用了错误的参数集并以 other 方式指定了类路径。
用 JPackage 替换 JClass,代码仍然有效。
import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JPackage('phylonet').coalescent.CommandLine.main([])
jpype.shutdownJVM()
由于您从类路径中提取 类 的方式是正确的,唯一可能的原因是指定了无效的参数集。删除后 -ea
代码仍然有效,所以你犯的错误在于这段代码。
'-Djava.class.path="%s"' % jar
事实上,我用这个来反对我的回答,砰,代码产生了这个:
TypeError: Package phylonet.coalescent.CommandLine.main is not Callable
这意味着,参数包含以下内容:
-Djava.class.path="astral.jar"
而不是跟随
-Djava.class.path=astral.jar
引号放错地方导致结果出错。
这是 JPype 的 classic 问题。如果无法加载 jar,则 JPackage 将 return 另一个不可调用的 JPackage。加载失败的常见原因包括
- 加载的JVM不支持jar的版本(检查getDefaultJVMPath()是否为旧版本)
- 缺少 jar 依赖项。
- JVM 找不到作为指定路径的 Jar。
以前的解决方案是使用 java.lang.Class.forName
,它会在加载 jar 时打印诊断信息。目前作为候选发布版本提供的 0.7.0 版本已经解决了这个问题。
此外,建议您在导入 class 时使用 jpype.imports
或 JClass
而不是 JPackage
。它更安全,因为它会报告更有意义的错误。例如:
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
您可以将包标记为符合(类 从上开始,包从下开始)以强制出错。
我试图打开一个 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()
我收到这个错误: 类型错误:包 phylonet.coalescent.CommandLine.main 不可调用
我已经提供了 jar 文件的绝对路径,并且我已经从 META-INF/MANIFEST.MF:
获得了主要功能cat tmp/META-INF/MANIFEST.MF | grep Main-Class
Main-Class: phylonet.coalescent.CommandLine
我尝试打开的 jar 文件名为 astral,来自此处:https://github.com/smirarab/ASTRAL
按预期方式调用它:
java -Djava.class.path="./astral.jar"
为什么我用 jpype 调用它时不呢?
首先,我已经在我自己的 jarfile 上测试了你的代码。确实,我遇到了这样的错误:
TypeError: Package clip.frontend.Start.main is not Callable
然后,仔细阅读文档后,我使用了另一种方法。
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()
并且输出是正确的:
% python2 main.py
2 2
+>+[<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>+<<<<<<<<<[-]>[-]>>>>>>>>[<<<<<<<<+>+>>>>>>>-]
<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[-]<<<<<<]<<<[>>+>+<<<-]>>[<<+>>-]>[[-]>>>>>>++
[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>[>>]+<<[<<]>[>[>>]
<+<[<<]>-]<<<<<<<[-]++[<<<<<+>>>>>>>>>>>>+<<<<<<<-]<<<<<[>>>>>+<<<<<-]>>>>>>>>>>>>>
[>>]+<<[<<]>[>[>>]<+<[<<]>-]<<<<<<<[-]#JVM has been shutdown
现在,我决定翻译我的解决方案来匹配您的问题:
import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JClass("phylonet.coalescent.CommandLine").main([])
jpype.shutdownJVM()
代码运行正常。比实际解决方案更重要的是,为什么您的代码不起作用。您使用了错误的参数集并以 other 方式指定了类路径。
用 JPackage 替换 JClass,代码仍然有效。
import jpype
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=astral.jar")
jpype.JPackage('phylonet').coalescent.CommandLine.main([])
jpype.shutdownJVM()
由于您从类路径中提取 类 的方式是正确的,唯一可能的原因是指定了无效的参数集。删除后 -ea
代码仍然有效,所以你犯的错误在于这段代码。
'-Djava.class.path="%s"' % jar
事实上,我用这个来反对我的回答,砰,代码产生了这个:
TypeError: Package phylonet.coalescent.CommandLine.main is not Callable
这意味着,参数包含以下内容:
-Djava.class.path="astral.jar"
而不是跟随
-Djava.class.path=astral.jar
引号放错地方导致结果出错。
这是 JPype 的 classic 问题。如果无法加载 jar,则 JPackage 将 return 另一个不可调用的 JPackage。加载失败的常见原因包括
- 加载的JVM不支持jar的版本(检查getDefaultJVMPath()是否为旧版本)
- 缺少 jar 依赖项。
- JVM 找不到作为指定路径的 Jar。
以前的解决方案是使用 java.lang.Class.forName
,它会在加载 jar 时打印诊断信息。目前作为候选发布版本提供的 0.7.0 版本已经解决了这个问题。
此外,建议您在导入 class 时使用 jpype.imports
或 JClass
而不是 JPackage
。它更安全,因为它会报告更有意义的错误。例如:
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
您可以将包标记为符合(类 从上开始,包从下开始)以强制出错。