2009-12-13 25 views
8

Tôi đang sử dụng Glassfish vừa cho ra mắt phiên bản 3 và trong khi sử dụng các thư viện nguồn gốc glassfish liên tục sẽ phàn nàn Glassfish tải thư viện bản địa (.dll, .so)

glassfish SEVERE: java.lang.UnsatisfiedLinkError: 
Native Library already loaded in another classloader

Thủ tục để tải thư viện bản địa trong việc phát hành glassfish trước (v2. 2) chỉ đơn giản là đặt các tập tin .dll trong GLASSFISH_HOME \ lib. Bây giờ tôi không biết nếu có một thư mục ma thuật trong v3 và nếu có làm cho biết. Tôi cũng đã kiểm tra màn hình quản trị và có hai biến tôi nghĩ có liên quan đến vấn đề của tôi: Tiền tố Đường dẫn Thư viện Gốc và Hậu tố Đường dẫn Thư viện Gốc. Tôi đã lùng sục internet để tìm một mô tả đầy đủ về những gì họ làm và cách tôi nên sử dụng chúng nhưng dường như không ai thích nói về chúng.

Trả lời

3

Điều đầu tiên: một lớp gốc đã cho chỉ có thể được tải vào một trình nạp lớp.

Điều thứ hai: mỗi ứng dụng web trong một thùng chứa servlet có trình nạp lớp của riêng nó.

Điều thứ ba: bạn phải rất cẩn thận khi mã hóa mã gốc để cho phép các lớp của nó được thu thập rác.

Kết quả: khi bạn tải mã gốc vào webapp, bạn có thể gặp phải các lỗi này nếu bạn cố gắng tải và tải lại.

Tôi ở một mức độ nào đó, bỏ qua biến thể thực sự đơn giản về chủ đề này: chỉ cần tải hai ứng dụng web khác nhau với cùng một lớp gốc.

Một số người thích tải mã gốc trong bộ nạp lớp hệ thống để tránh vấn đề này.

4
java.lang.UnsatisfiedLinkError: Native Library already loaded in another classloader 

Một lib bản địa chỉ có thể được nạp một lần trong JVM và bạn sẽ nhận được thông báo lỗi bất cứ khi nào bạn tải một phiên bản mới của lớp gọi (các lớp học, nơi các cuộc gọi System.loadLibrary(String) cư trú) trên một redeploy. Thông tin thêm về điều này bên dưới.

Quy trình tải thư viện gốc trong bản phát hành thủy tinh trước đó (v2.2) chỉ đơn giản là đặt các tệp .dll trong GLASSFISH_HOME\lib.

Vâng, đây thực sự chỉ là phần đầu tiên của câu chuyện. Để tải một thư viện gốc, bạn có tất nhiên để đặt nó trên đường dẫn thư viện để tải nó từ mã Java. Để làm như vậy, quy ước là bao gồm một initializer tĩnh như thế này:

class FooWrapper { 
    static { 
     System.loadLibrary("foo"); 
    } 

    native void doFoo(); 
    } 
} 

Giả sử bạn đang làm việc với một ứng dụng web, một thực hành tốt nhất là nên đặt các thư viện nguồn gốc HOẶC giao diện JNI mình theo WEB-INF/lib hoặc WEB-INF/classes để tránh các vấn đề khi tải lại ứng dụng, như đã đề cập ở trên. Nói cách khác, lớp gọi là System.loadLibrary(String) sẽ được tải bởi trình nạp lớp không bị ảnh hưởng bởi việc tải lại ứng dụng web.

Vì vậy, câu hỏi của tôi là: bạn đã đặt mã đó ở đâu?

PS: Một tùy chọn khác là kiểm tra xem tệp dll đã có sẵn trước khi tải chưa nhưng tôi sẽ không làm điều đó.

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