JNIを使用して静的なJavaメソッドを呼び出すと、スイングJFrameが作成され、表示されます。コードはかなりシンプルで、JavaコードはJNIを使用してCから呼び出されたときにスタンドアロンで動作します(つまり、java StartAWT
が必要です)。プロセスがハングします。Java JNI:CからのJNIを使用したスイングウィンドウの作成
私はMac OS X 10.8 Mountain LionでJDK 1.7.0_09を使用しています。
これは、私は、静的メソッドを呼び出すために使用しているCコードです:
JavaVM* jvm;
JNIEnv* env = create_vm(&jvm);
jclass class = (*env)->FindClass(env, "StartAWT");
jmethodID method = (*env)->GetStaticMethodID(env, class, "run", "()V");
(*env)->CallStaticVoidMethod(env, class, method);
(*jvm)->DestroyJavaVM(jvm);
StartAWT
クラスは次のようになります。私は、アプリケーションを起動すると
public class StartAWT {
public static class Starter implements Runnable {
public void run() {
System.out.println("Runnning on AWT Queue.");
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("That's a frame!");
JLabel label = new JLabel("A Label");
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
}
public static class GUI implements Runnable {
public void run() {
try {
System.out.println("Going to put something on the AWT queue.");
SwingUtilities.invokeAndWait(new Starter());
} catch (Exception exc) {
throw new RuntimeException(exc);
}
}
}
public static void run() {
Thread gui = new Thread(new GUI());
gui.start();
}
}
、私はGoing to put something on the AWT queue
を見ていますしかしRunning on AWT Queue
ではありません。
私のCプロセス内の仮想マシンはAWTイベントキューを持っていないと思いますが、それを設定する方法もわかりません(これは理由もありません)。
JNIを使用してAWTベースのGUIを表示するにはどうすればよいですか?
-
編集:私は、スレッドが生きているとどのは(this gistで見ることができる)されていないかを確認するためにループを挿入した。このバージョンでは、別のスレッドでSwingUtilities.invokeAndWait
の呼び出しを行います。結果:メインスレッドは生きています(C)。 Java(メインスレッドではない)によってディスパッチされた最初のスレッドは生きています。呼び出しinvokeAndWait
を実行しているスレッドはブロックされています(私はinvokeAndWaitが返されたとは思わない)、EventQueueで実行される関数は入力されていません。
私も次のようなメッセージを与えるであろう、直接SwingUtilities.invokeAndWait
を起動しようとしました:これは私は1つのコメントで示唆したような、ここでStackOverflowの上の他の質問には何を読んでもある
2013-02-02 13:50:23.629 swing[1883:707] Cocoa AWT: Apple AWT Java VM was loaded on first thread -- can't start AWT. (
0 liblwawt.dylib 0x0000000117e87ad0 JNI_OnLoad + 468
1 libjava.dylib 0x00000001026076f1 Java_java_lang_ClassLoader_00024NativeLibrary_load + 207
2 ??? 0x000000010265af90 0x0 + 4335185808
)
を以下。しかし、私は元の問題の解決策を見つけることができませんでした。おそらく、上記のメッセージが現れた後、メインスレッドがまだ生きている、つまりプロセスデッドロックもクラッシュも起こっていないことに気付くかもしれません。
-
EDIT:予想通り、私はそれが動作しているLinux上でコードをテストしました。だから私はこれがCocoa AWTのMac OS Xの問題だと思っていますが、それを回避する方法はわかりません。
-
EDIT:私はまた、新しいネイティブスレッドにJVMの全体の呼び出しを動かしてみました。これはMac OS X 10.6でApples Java 32ビット(1.6.0_37)で動作しますが、上記と同じデッドロックが発生します。 Mac OS X 10.8では、アプリケーションが「Trace/BPT trap:5」(seems to be related to loading dynamic libraries)という唯一のメッセージで壊れてしまいます。
Iはまた、in this Q&Aを説明するが、起動が不明のエラーでメッセージlsopenurlswithrole() failed with the message -10810
、で失敗し、りんごLaunch Services Referenceに従ってとしてバイナリを束ねてみました。後者はAWTを使用しようとせずにも発生します(単なるJVM呼び出しは失敗します)。
この[Q&A](http://stackoverflow.com/q/8750690/230513)も参照してください。 – trashgod
ありがとう、私はそのQ&Aをチェックし、私のアプリケーションで遊んだ。しかし、それはすべての後に動作しません(他の質問のように、そこに解決策も与えられていません)。 – scravy
私は同様の結果を得ました。私は 'JavaApplicationStub'を使うだけですが、どのように動作するのか分かりません。私は 'JVM TI'(ここではhttp://stackoverflow.com/a/14492574/230513)に関連する何かがあるかどうか疑問に思います。 – trashgod