Phân tích
Các bộ phận JDK, dựa trên COM được khởi tạo (D3DPipeline, âm thanh và cửa sổ ShellFolder truy cập) tất cả làm theo cùng một khuôn mẫu:
- chạy mã trong một thread riêng biệt
- cho chủ đề này
CoInitialize
được gọi
- ở phần cuối của mã mức người dùng
CoUnitialize
được gọi
Điều này phù hợp với tài liệu mà MSDN giữ cho COM và phân tích là chính xác, lỗi cho biết rằng hệ thống con COM đã được khởi tạo thành chuỗi MTA.
Vì vậy, tôi sửa đổi trình chạy java (jvm.dll) và chèn tuyên bố gỡ lỗi vào một số phương pháp có nguồn gốc trong os_windows.cpp. Tôi tập trung vào các phương pháp luồng. Những gì tôi thấy được điều này:
create_main_thread
, create_os_thread
, pd_start_thread
tất cả chạy với COM chưa khởi
- initializer chủ đề quê hương (
thread_native_entry
) đã chạy với COM khởi
Tôi nhìn nhiều hơn vào trong _beginthreadex
và thực sự tôi cuối cùng đã tìm thấy một dẫn trên stackoverflow. Điều đó đã chỉ cho tôi mã nguồn của threadex.c, là một phần của cài đặt Visual Studio 2013 Express.
Ở đó bạn thấy rằng _beginthreadex
không trực tiếp bắt đầu chức năng chuỗi được cung cấp, nhưng chạy bộ khởi tạo thư viện (_threadstartex
) trước tiên.Một phần của initializer này lần đọc:
_ptd->_initapartment = __crtIsPackagedApp();
if (_ptd->_initapartment)
{
_ptd->_initapartment = _initMTAoncurrentthread();
}
_callthreadstartex();
_crtIsPackagedApp
phát hiện qua một hàm kernel nếu ứng dụng là chạy như là một "PackagedApp" (tức là gói phụ lục) và nếu như vậy, thì RoInitialize
hàm được gọi, mà từ tôi sự hiểu biết hành vi như anh em lớn của CoInitialize.
Tóm tắt câu chuyện dài: Nếu ứng dụng của bạn được tạo bằng Visual Studio 2013 và chạy dưới dạng ứng dụng đóng gói, bạn sẽ gặp phải một môi trường bị hỏng.
Nó đã được xác nhận, rằng các phiên bản làm việc của Oracle JDK được xây dựng với VS2010 SP1 và phiên bản bị hỏng được xây dựng với VS2013SP4.
Cách giải quyết
Với các thông tin trên google cuối cùng tìm thấy một tài liệu tham khảo, hỗ trợ phân tích:
https://blogs.msdn.microsoft.com/vcblog/2016/07/07/using-visual-c-runtime-in-centennial-project/
Trích dẫn từ bài viết rằng:
Note that the existing VC++ 12.0 libraries created during the Windows 8 timeframe have runtime checks to determine whether the app is running under the app container or not. When running desktop apps as a packaged app, these checks might limit the functionality of the desktop app or cause it to behave like a UWA (Universal Windows Application) (limited file system access or create thread initializing MTA etc.). We have fixed this behavior in the VC++ libraries contained in these framework packages and thus removing the modern app limitations from your desktop applications.
Vì vậy, tôi thấy để lựa chọn để sửa các ứng dụng, sẽ được phân phối dưới dạng gói AppX:
- hoặc buộc người sử dụng phải có bản cập nhật VC++ 12,0 mã nhị phân được cài đặt (bằng cách giới thiệu các phụ thuộc được trích dẫn trong các bài viết trên blog) hoặc
- thay thế
msvcr120.dll
mà đi kèm với Java 9 (và tôi cũng giả Java 10) với phiên bản cố định từ gói cập nhật
Tôi sẽ sử dụng phiên bản thứ hai và tôi đã thử nghiệm điều này. Bắt đầu với một hệ thống Windows 10 sạch mới nhất, tôi đã cài đặt JDK 9.0.4, tôi nhân bản testcase được cung cấp, sửa đổi nó sử dụng JRE được cài đặt cục bộ (không phải là JDK!) Và xây dựng gói appx. Chạy này, tôi sao chép vấn đề. sau đó tôi thay thế msvcr120.dll
's trong thư mục JRE cài đặt hệ thống của tôi với một chứa trong các thùng chứa phụ lục từ:
https://www.microsoft.com/en-us/download/details.aspx?id=53176
Gợi ý: * .appx chỉ là file ZIP có chữ ký bổ sung, vì vậy bạn có thể chỉ cần đổi tên và trích xuất nội dung.
Tôi xây dựng lại testcase và nó hoạt động như bình thường (không có COM lỗi khởi tạo nữa).
Một kết xuất chuỗi có thể sẽ là một cái nhìn sâu sắc hơn và báo cáo điều này để mở danh sách gửi thư jdk, trình theo dõi lỗi vv cũng sẽ hữu ích. – nullpointer
Không chắc chắn nếu chúng có liên quan, nhưng hãy xem [JDK-8189604] (https://bugs.openjdk.java.net/browse/JDK-8189604) – nullpointer
Bạn có thể chưng cất điều này xuống một trường hợp thử nghiệm nhỏ mà tái tạo vấn đề sao cho nó có thể được đính kèm vào https://bugs.openjdk.java.net/browse/JDK-8189938. –