2009-12-29 32 views
13

Tôi là người mới sử dụng Java và chỉ bắt đầu tìm ra khái niệm về trình nạp lớp. Ngay bây giờ tôi đang gặp một số vấn đề với log4j về việc sử dụng trình nạp lớp ngữ cảnh của luồng.log4j và trình nạp lớp ngữ cảnh chủ đề

tôi nhận được các lỗi sau đây: A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable. The class "org.apache.log4j.Appender" was loaded by [[email protected]] whereas object of type "org.apache.log4j.ConsoleAppender" was loaded by [[email protected]]. Could not instantiate appender named "CONSOLE".

ứng dụng tôi làm việc khoảng cách này: Trên init URLClassLoader # 1 được xây dựng và tải một số lớp học, các lớp này sử dụng log4j. Sau đó, URLClassLoader # 2 được xây dựng (có URLClassLoader # 1 làm cha mẹ của nó) và tải thêm một số lớp, các lớp này cũng sử dụng log4j. Khi URLClassLoader # 2 được sử dụng để tải các lớp này, thông báo lỗi trên xuất hiện (có thêm một vài vấn đề nữa với cùng một vấn đề).

Cách giải quyết hiện nay tôi làm là để thiết lập classloader chủ đề bối cảnh hiện nay để URLClassLoader # 2 trước khi tải các lớp có vấn đề, và đặt nó vào cái cũ sau:

ClassLoader urlClassLoader; // this is URLClassLoader #2 
Thread thread = Thread.currentThread(); 
ClassLoader loader = thread.getContextClassLoader(); 
thread.setContextClassLoader(urlClassLoader); 
try { 
    urlClassLoader.loadClass(...) 
} finally { 
    thread.setContextClassLoader(loader); 
} 

Trong khi làm việc này, tôi không chắc chắn nếu đó là cách tiếp cận đúng.

Bất kỳ thông tin chi tiết nào về vấn đề này sẽ được đánh giá cao. Ngoài ra, tại sao log4j buộc tôi phải lộn xộn với trình nạp lớp ngữ cảnh của luồng? Tại sao không cho phép tôi vượt qua trong một bộ nạp lớp (và sử dụng một mặc định khi tôi không) thay vì sử dụng một trong những chủ đề?

+0

Bạn đã cứu cuộc sống của tôi với câu hỏi của bạn, tôi đã bị mắc kẹt trong 3 ngày với vấn đề tương tự! Tôi chưa đặt "thread.setContextClassLoader", và với điều đó thì tốt! Nó thực sự tốt đẹp mặc dù bạn là một newbie trong java! –

Trả lời

15

Có vẻ như bạn đã gặp phải vấn đề lớn với log4j (và thư viện Apache Commons Logging), cụ thể là họ có một thời gian khó khăn phát hiện và tương tác với trình nạp lớp phù hợp khi chúng được sử dụng. Có một lời giải thích rất dày đặc, hoàn chỉnh với các ví dụ, here; thông điệp mang về nhà là một trong những động lực chính cho khung khai thác gỗ mới SLF4J là loại bỏ hoàn toàn các vấn đề này. Bạn có thể muốn trao đổi nó và xem cuộc sống của bạn có dễ dàng hơn không.

+0

Tôi không chắc liệu chúng tôi có thể bắt đầu sử dụng cái gì khác vào thời điểm này hay không. Cách đề xuất để đối phó với vấn đề log4j này là gì? –

+1

Thành thật mà nói, tôi không thể nói, bởi vì đó là một vấn đề đủ tồi tệ mà giờ đây tôi đã tránh được log4j và đăng nhập Apache Commons một cách chắc chắn. Thực tế, mặc dù, bạn sẽ có thể di chuyển đến SLF4J tầm thường - xem http://www.slf4j.org/legacy.html để biết thông tin về cách SLF4J đi kèm với "bộ điều hợp cầu" cho phép mã của bạn vẫn thực hiện cuộc gọi đến log4j và có những cuộc gọi bị chặn bởi SLF4J. Bằng cách này, bạn có thể sử dụng SLF4J một cách tự nhiên trong bất kỳ mã mới nào và di chuyển mã cũ, log4j-utilizing sang SLF4J lúc rảnh rỗi của bạn. – delfuego

+0

+1 cho gợi ý để tránh Log4j và JCL. Chúng được thay thế bởi SLF4j, cũng có các lớp tương thích cho log4j và jcl. Chúng tôi đã làm điều đó trong TẤT CẢ các dự án của chúng tôi vì những lý do chính xác. – mhaller

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