我正在使用Jpype将java类用于python脚本。 java类涉及使用AWT库:这似乎是问题所在。
这是python脚本:
import jpype
import os.path
import threading
jarpath = os.path.join(os.path.abspath('.'), 'build/jar')
target=jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % jarpath)
Capture = jpype.JClass('Capture') # Capture is the class, contained in ./ folder
t = Capture(50,354,90,90,130,650,"num",36); # create the instance
jpype.shutdownJVM()
所以我只是试图实例化该类,然后退出。 这是java类。我只报告导致错误的代码:
class Capture {
public Capture(int x, int y, int width, int height, int mouseNextX, int mouseNextY, final String fnamestart, final int countmax) {
//...
images = new ArrayList<BufferedImage>();
getImages(fnamestart,countmax); //THIS is the problem
}
// reference to getImages() method:
public void getImages(String fname, int countmax) {
images.clear();
for(int i=0; i<=countmax; i++) {
try {
BufferedImage img = ImageIO.read(new File(fname+i+".bmp"));
images.add(img);
} catch(IOException e) {
images.add(null);
}
}
}
}
此代码在运行python脚本时,引发以下错误:
jpype._jexception.VirtualMachineErrorPyRaisable: java.lang.InternalError: Can't start
the AWT because Java was started on the first thread. Make sure StartOnFirstThread is
not specified in your application's Info.plist or on the command line
长话短说,这是一个众所周知的问题:Eclipse有“自己的版本”,然后解决了。不幸的是,没有人谈到与jpype相关的这个问题。
我尝试了这些没有用的解决方案:
在python脚本中,在启动JVM之前启动一个线程。然后在另一个线程中启动JVM。
在python脚本中,使用参数-XstartOnFirstThread
:
target=jpype.startJVM(jpype.getDefaultJVMPath(), "-XStartOnFirstThread -Djava.ext.dirs=%s" % jarpath)
在java代码中:使用AWT方法invokeLater
,在构造函数中:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
images = new ArrayList<BufferedImage>();
getImages(fnamestart,countmax);
}
});
我真的不知道该怎么做,希望你会帮助我。 谢谢,
乔瓦尼
答案 0 :(得分:1)
使用此参数:
jpype.startJVM(jpype.getDefaultJVMPath(), '-Djava.awt.headless=true')
答案 1 :(得分:0)
-XstartOnFirstThread
正是您必须确保不才能拥有命令行。在python中启动一个线程没有任何区别,问题在于JVM的线程。 invokeLater
也没有区别 - AWT运行循环必须在第一个线程上执行。这是一个仅限Cocoa的限制,所以我想你是在Mac上运行它。
现在,您应该通过查看用于启动JVM的确切命令行,然后尝试追溯到根本原因(生成该命令行的代码)来搜索您的问题。 JVM是通过您可以直接控制的方法启动的。