創建使用JNI Swing的窗口我使用JNI調用這反過來又創造一個Swing的JFrame,並顯示一個靜態的Java方法。代碼非常簡單,Java代碼獨立工作(即java StartAWT
做它應該做的事情),而當使用JNI從C調用時,該過程掛起。Java的JNI:由C
我使用的是Mac OS X 10.8山獅的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基於圖形用戶界面來完成?
-
編輯:我插入循環,看看哪個線程是活的,未(可在this gist看到)。在這個版本中,我在另一個線程中調用SwingUtilities.invokeAndWait
。結果:主線程是活着的(C)。 Java調度的第一個線程(不是主線程)是活着的;線程做電話invokeAndWait
被封鎖(我不認爲invokeAndWait甚至沒有返回),甚至沒有進入這應該在EventQueue運行的功能。
我也試過直接調用SwingUtilities.invokeAndWait
,這將給以下消息:
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
)
這也是我在其他問題已經讀到這裏在計算器上,比如一個在意見建議下面。但是,我找不到解決原始問題的方法。也許值得注意的是,在上面的消息出現之後,主線程仍然存在,即進程死鎖和崩潰都沒有。
-
編輯:我測試的代碼在Linux上它工作正常。所以我認爲這是Cocoa AWT的Mac OS X問題,但我不知道如何繞過它。
-
編輯:我也嘗試了JVM的整個調用移動到一個新的本地線程。這適用於蘋果Java 32位(1.6.0_37)的Mac OS X 10.6,但會導致與上述相同的死鎖。在Mac OS X 10.8上,情況更糟糕,應用程序使用唯一消息「Trace/BPT陷阱:5」(其中seems to be related to loading dynamic libraries)激化。
我也嘗試打包二進制文件,如in this Q&A所述,但發佈失敗,消息爲lsopenurlswithrole() failed with the message -10810
,根據Apples Launch Services Reference,這是一個未知錯誤。後者也會發生,而不會嘗試使用AWT(僅僅是JVM調用失敗)。
另請參閱此[問與答](http://stackoverflow.com/q/8750690/230513)。 – trashgod
謝謝,我已經檢查過這個問答,並且在我的應用程序中玩過。但它畢竟不起作用(如另一個問題,也沒有解決方案)。 – scravy
我得到了類似的結果;我只是使用'JavaApplicationStub',但我不知道它是如何工作的。我想知道'JVM TI',引用[這裏](http://stackoverflow.com/a/14492574/230513),有什麼相關的。 – trashgod