Tôi đang sử dụng JNI để gọi một phương thức java tĩnh để tạo ra một Swing JFrame và hiển thị nó. Mã này khá đơn giản và mã Java hoạt động độc lập (tức là java StartAWT
thực hiện những gì cần) trong khi được gọi từ C bằng cách sử dụng JNI, quy trình bị treo.Java JNI: Tạo cửa sổ xoay bằng JNI từ C
Tôi đang sử dụng JDK 1.7.0_09 trên Mac OS X 10.8 Mountain Lion.
Đây là mã C Tôi đang sử dụng để gọi phương thức tĩnh:
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);
Lớp StartAWT
trông như thế này:
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();
}
}
Khi tôi khởi động ứng dụng, tôi thấy Going to put something on the AWT queue
nhưng không phải là Running on AWT Queue
.
Tôi tin rằng Máy ảo trong quy trình C của tôi không có hàng đợi sự kiện AWT nhưng tôi không biết cách thiết lập để có một (hoặc tôi chắc chắn rằng đây là lý do).
Điều gì sẽ được thực hiện để hiển thị GUI dựa trên AWT bằng JNI?
-
EDIT: Tôi đã chèn vòng để xem những chủ đề còn sống và không được (có thể được nhìn thấy trong this gist). Trong phiên bản này tôi thực hiện lời gọi SwingUtilities.invokeAndWait
trong một chủ đề khác. Kết quả: Chủ đề chính còn sống (C). Luồng đầu tiên được gửi đi bởi Java (không phải luồng chính) là còn sống; các chủ đề làm các cuộc gọi invokeAndWait
bị chặn (Tôi không nghĩ rằng invokeAndWait thậm chí đã trở lại), chức năng cần được chạy trên EventQueue thậm chí không được nhập.
Tôi cũng đã cố gắng gọi SwingUtilities.invokeAndWait
trực tiếp, mà sẽ cung cấp được thông báo sau:
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
)
Đây cũng là những gì tôi đã đọc trong các câu hỏi khác ở đây trên StackOverflow, chẳng hạn như một trong những gợi ý trong các ý kiến phía dưới. Tuy nhiên, tôi không thể tìm thấy một giải pháp cho vấn đề ban đầu. Có thể đáng chú ý là sau khi thông báo trên xuất hiện, luồng chính vẫn còn sống, tức là không có quá trình bế tắc cũng như sự cố.
-
EDIT: Tôi đã thử nghiệm mã trên Linux, nơi nó được làm việc như mong đợi. Vì vậy, tôi tin rằng đây là một vấn đề với Mac OS X với Cocoa AWT, nhưng tôi không biết làm thế nào để phá vỡ nó.
-
EDIT: Tôi cũng đã cố gắng di chuyển toàn bộ gọi của JVM lên một chủ đề quê hương mới. Điều này làm việc trên Mac OS X 10.6 với Apple 32 bit (1.6.0_37), nhưng kết quả trong cùng một bế tắc như được mô tả ở trên. Trên Mac OS X 10.8, điều này tệ hơn, ứng dụng sẽ đổ xuống với thông điệp duy nhất "Trace/BPT trap: 5" (trong đó seems to be related to loading dynamic libraries).
Tôi cũng đã cố gắng bundling nhị phân như mô tả in this Q&A, nhưng sự ra mắt không thành công với thông điệp lsopenurlswithrole() failed with the message -10810
, đó là một lỗi không rõ, theo Táo Launch Services Reference. Cái sau cũng xảy ra mà không cố gắng sử dụng AWT (lời gọi JVM chỉ thất bại).
Xem thêm [Hỏi đáp] này (http://stackoverflow.com/q/8750690/230513). – trashgod
Cảm ơn, tôi đã kiểm tra phần Hỏi & Đáp và chơi với ứng dụng của tôi; nhưng nó không hoạt động sau khi tất cả (như trong câu hỏi khác, không có giải pháp được đưa ra có quá). – scravy
Tôi nhận được kết quả tương tự; Tôi chỉ sử dụng 'JavaApplicationStub', nhưng tôi không biết nó hoạt động như thế nào. Tôi tự hỏi nếu 'JVM TI', trích dẫn [ở đây] (http://stackoverflow.com/a/14492574/230513), có bất cứ điều gì có liên quan. – trashgod