3

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 スクリプトで、パラメーターを使用して JVM を開始します-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);
        }
    });
    

あなたが私を助けてくれることを願って、私は本当に何をすべきかわかりません。ありがとうございました、

ジョバンニ

4

2 に答える 2

0

-XstartOnFirstThreadコマンドラインで使用しないようにする必要があるのは、まさにそれです。Python でスレッドを起動しても違いはありません。問題は JVM のスレッドにあります。invokeLaterこれも違いはありません。AWT 実行ループは最初のスレッドで実行する必要があります。これは Cocoa のみの制限なので、これを Mac で実行していると思います。

ここで、JVM の起動に使用されたコマンド ラインを正確に確認して問題を検索し、根本原因 (そのコマンド ラインを生成したコード) を追跡する必要があります。JVM は、直接制御できない方法によって起動されています。

于 2012-07-07T11:04:18.987 に答える