2009-12-29 17 views
13

मैं जावा के लिए नौसिखिया हूं और बस कक्षा लोडर की अवधारणा को समझना शुरू कर रहा हूं। अभी मुझे थ्रेड संदर्भ क्लासलोडर के उपयोग के संबंध में log4j के साथ कुछ समस्याएं हैं।log4j और थ्रेड संदर्भ क्लासलोडर

मैं निम्नलिखित त्रुटियाँ हो रही है: 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".

मेरा आवेदन मोटे तौर पर इस तरह से काम करता है: पर # 1 init URLClassLoader निर्माण किया है और लोड हो जाता है कुछ कक्षाएं, इन कक्षाओं log4j का उपयोग करें। बाद में URLClassLoader # 2 पर बनाया गया है (जिसमें URLClassLoader # 1 इसके माता-पिता के रूप में है) और कुछ और कक्षाएं लोड करती हैं, ये कक्षाएं log4j का भी उपयोग करती हैं। जब URL क्लासलोडर # 2 इन वर्गों को लोड करने के लिए उपयोग किया जाता है तो उपरोक्त त्रुटि संदेश प्रकट होता है (एक ही समस्या के साथ कुछ और हैं)।

वर्तमान वैकल्पिक हल मैंने किया समस्याग्रस्त वर्गों लोड हो रहा है, और बाद में वर्ष एक के लिए रीसेट करने से पहले URLClassLoader # 2 के लिए वर्तमान धागा संदर्भ classloader स्थापित करने के लिए किया गया था:

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

हालांकि यह काम करता है, मैं नहीं कर रहा हूँ सुनिश्चित करें कि यह सही दृष्टिकोण है।

इस मामले पर किसी भी अंतर्दृष्टि की सराहना की जाएगी। इसके अलावा, log4j मुझे थ्रेड संदर्भ क्लासलोडर के साथ गड़बड़ करने के लिए मजबूर क्यों कर रहा है? थ्रेड के उपयोग के बजाय मुझे क्लास लोडर में क्यों नहीं जाने दें (और जब मैं नहीं करता तो डिफ़ॉल्ट का उपयोग करें)?

+0

आपने मेरे जीवन को अपने प्रश्न से बचाया, मैं इसी तरह की समस्या के साथ 3 दिनों तक फंस गया था! मैंने "thread.setContextClassLoader" सेट नहीं किया है, और इसके साथ यह ठीक है! जावा में नौसिखिया होने के बावजूद यह वास्तव में अच्छा है! –

उत्तर

15

आप log4j (और अपाचे कॉमन्स लॉगिंग लाइब्रेरी) के साथ बड़ी समस्या पर ठोकर खा चुके हैं, अर्थात् उनके पास उपयोग किए जा रहे सही क्लासलोडर्स के साथ एक हास्यास्पद कठिन समय है और बातचीत कर रहा है। एक बहुत घना स्पष्टीकरण है, उदाहरणों के साथ पूर्ण, here; ले-होम संदेश यह है कि नए लॉगिंग फ्रेमवर्क SLF4J के लिए प्राथमिक ड्राइविंग बलों में से एक पूरी तरह से इन मुद्दों को खत्म करना था। आप इसे स्वैप करना चाहते हैं और देख सकते हैं कि आपका जीवन आसान हो गया है या नहीं।

+0

मुझे यकीन नहीं है कि इस बिंदु पर किसी और चीज का उपयोग शुरू करना हमारे लिए संभव है। इस log4j मुद्दे से निपटने का सुझाया गया तरीका क्या है? –

+1

ईमानदारी से, मैं नहीं कह सकता, क्योंकि यह एक खराब मुद्दा है कि अब मैं दृढ़तापूर्वक log4j और अपाचे कॉमन्स लॉगिंग से बचता हूं। वास्तव में, हालांकि, आप SLF4J को तीन बार माइग्रेट करने में सक्षम होना चाहिए - http://www.slf4j.org/legacy.html देखें कि कैसे SLF4J "पुल एडेप्टर" के साथ आता है जो आपके कोड को अभी भी log4j पर कॉल करने की अनुमति देता है और उन कॉलों को एसएलएफ 4 जे द्वारा अवरुद्ध किया गया है। इस तरह, आप किसी भी नए कोड में मूल रूप से SLF4J का उपयोग कर सकते हैं, और अपने अवकाश पर पुराने, log4j-उपयोग कोड को SLF4J पर माइग्रेट कर सकते हैं। Log4j और JCL से बचने के लिए संकेत के लिए – delfuego

+0

+1। उन्हें एसएलएफ 4 जे द्वारा प्रतिस्थापित किया गया है, जिसमें log4j और jcl के लिए संगतता परत भी है। हमने उन सभी कारणों से हमारी सभी परियोजनाओं में ऐसा किया है। – mhaller