2012-05-04 25 views
8

Tôi có một ứng dụng Windows MFC rằng:JNI_CreateJavaVM() thất bại mỗi khi khác tôi chạy ứng dụng của tôi (chính xác)

(1) Nạp JVM (JNI_CreateJavaVM())

(2) Gắn các chủ đề chính để JVM (AttachCurrentThread())

(3) Nạp một số lớp Java và phương pháp (FindClass()GetMethodID()/GetStaticMethodID())

(4) Thanh ghi một số callbacks mẹ đẻ để sử dụng bởi mã Java (RegisterNatives())

(5) tách sợi từ JVM (DetachCurrentThread())

(6) Phá hủy JVM (DestroyJavaVM())

Tất cả các chức năng trên thành công mỗi lần khác Tôi chạy ứng dụng. Tôi biết họ thành công, bởi vì, ngoài ra, tôi tương tác với ứng dụng và gọi thành công các phương thức tĩnh Java, và các phương thức Java này gọi thành công các callback gốc của tôi. Ứng dụng của tôi thoát ra một cách duyên dáng và chắc chắn rằng các hàm Java dự kiến ​​và các cuộc gọi lại tự nhiên đã được thực hiện.

Tuy nhiên, mỗi lần khác mà tôi chạy ứng dụng, cuộc gọi đến JNI_CreateJavaVM() không thành công (không điền JavaVM *). Hoàn toàn không có gì thay đổi giữa các lần chạy ứng dụng. Tôi chỉ cần chạy nó một lần (thành công, thậm chí mà không cần làm bất cứ điều gì ngoại trừ 6 bước trên), thoát một cách duyên dáng, chạy lại và không thành công, qua lại. Không có ngoại lệ đối với sự thành công/thất bại về sau-và-ra - tôi có thể chạy nó hàng chục lần, và nó dao động chính xác vào mọi thời điểm khác giữa thành công, và thất bại trên đường dây JNI_CreateJavaVM().

Nếu cần, tôi sẽ dán thêm mã. Tuy nhiên, tôi hy vọng ai đó có một cái nhìn sâu sắc với những gì tôi đã cung cấp. (Lưu ý: đây là ứng dụng thuộc tính BCGSoft MFC, mặc dù tôi rất nghi ngờ vấn đề đó.)

+1

Và bởi "mỗi khi tôi chạy ứng dụng" bạn thực sự có nghĩa là bạn bắt đầu toàn bộ quá trình mỗi lần, phải không? Không chỉ có hai cuộc gọi phương thức trong một quy trình đơn lẻ? –

+0

Chính xác. Trong trường hợp của tôi, tôi chạy trong chế độ Debug và nhấn F5 trong Visual Studio để chạy ứng dụng. Sau đó, tôi thoát khỏi ứng dụng hoàn toàn. –

+0

Tôi nghĩ rằng ít nhất là chỉnh sửa và thêm mã gọi JNI_CreateJavaVM, đặc biệt là cách bạn cư trú các arg. –

Trả lời

4

Có vẻ như bạn đang chạy vào this bug (được khôi phục here) có thể sẽ không bao giờ được sửa.

Mặc dù tên của nó, DestroyJavaVM() không thực sự phá hủy JVM. Những gì nó làm là báo hiệu JVM mà nó sẽ tắt, nhưng JVM thực sự đợi cho đến khi tất cả các luồng khác với luồng Main đã dừng trước khi nó thực sự tắt. Trong thực tế, thậm chí sau đó nó không hoàn toàn làm sạch sau khi chính nó, như là the documentation tiểu bang (khá cryptically): "JDK/JRE vẫn không hỗ trợ VM dỡ, tuy nhiên."

Ngoài ra, tôi lo lắng về bước 2 của bạn, "Đính kèm chuỗi chính vào JVM". Bạn không cần phải đính kèm luồng đã tạo JVM vào JVM và bạn không thể tách luồng đó ra. Nếu bạn thực sự làm điều đó, thì có thể đó là những gì đang làm rối loạn hệ thống của bạn. (Chủ đề tạo JVM là luồng "Main" của JVM. Bạn chỉ cần đính kèm/tách các chuỗi gốc khác với JVM nếu chúng cần truy cập vào nó.)

Bằng cách này, JNI_CreateJavaVM() trả về 0 thành công, và bạn nói nó trả về 0 lần "thất bại", vì vậy trong ý nghĩa nào là nó thất bại? Bạn đang sử dụng JVM nào (phiên bản, nhà cung cấp)?

+0

Về giá trị trả về là 0 - thực ra, 'JNI_CreateJavaVM()' không trả về 0; cảm ơn vì đã chỉ ra điều này - đó là một hàm bao bọc bên trong mã của ứng dụng trả về NULL; Tôi đã xóa nội dung đó khỏi câu hỏi của mình. Về bước 2 của tôi - Tôi sẽ xem xét điều đó sớm và đăng một bình luận khác. –

+0

Ngoài nhận xét ở trên, một câu hỏi: Bạn có nghĩ rằng có thể lỗi mà bạn đã tham chiếu có thể áp dụng ngay cả trong trường hợp của tôi, trong đó hành vi quay lại và xảy ra giữa * chạy * của ứng dụng - thay vì trong một lần chạy? –

+0

@Dan, vâng tôi nghĩ rằng lỗi có thể áp dụng bởi vì bạn đang chạy chương trình từ bên trong Visual Studio. Nếu bạn đọc các ý kiến ​​về lỗi, bạn sẽ thấy một người khác có cùng một vấn đề do Visual Studio tái sử dụng các Debug thread. –

Các vấn đề liên quan