क्या कारण और क्या NoClassDefFoundError और ClassNotFoundException के बीच अंतर हैं?


371

बीच क्या अंतर है NoClassDefFoundErrorऔर ClassNotFoundException?

उन्हें फेंकने के लिए क्या कारण हैं? उनका समाधान कैसे हो सकता है?

जब मैं नई जार फ़ाइलों को शामिल करने के लिए मौजूदा कोड को संशोधित करता हूं, तो मैं अक्सर इन थ्रोबल का सामना करता हूं। मैंने उन्हें क्लाइंट साइड और सर्वर साइड पर वेबस्टार्ट के माध्यम से वितरित एक जावा ऐप के लिए मारा है।

संभावित कारण जो मेरे सामने आए हैं:

  1. build.xmlकोड के ग्राहक पक्ष के लिए पैकेज शामिल नहीं हैं
  2. हम जो नए जार इस्तेमाल कर रहे हैं, उनके लिए रनटाइम क्लासपाथ गायब है
  3. संस्करण पिछले जार के साथ संघर्ष करता है

जब मैं आज इनका सामना करता हूं, तो मैं चीजों को काम करने के लिए एक राह-और-त्रुटि दृष्टिकोण लेता हूं। मुझे और अधिक स्पष्टता और समझ की आवश्यकता है।


मैं अक्सर जेवीएम के साथ दौड़ता हुआ पाता हूं -verbose(जैसे -verbose:class -verbose:jni) मदद करता है - लेकिन उनके जवाब के नीचे मोगी की रिपोर्ट है कि इससे कोई अतिरिक्त उपयोगी जानकारी नहीं मिलती है :(
PJTraill

जवाबों:


388

जावा एपीआई विनिर्देशों से अंतर इस प्रकार है।

के लिए ClassNotFoundException:

जब कोई एप्लिकेशन अपने स्ट्रिंग नाम के माध्यम से कक्षा में लोड करने का प्रयास करता है, तो उसे फेंक दें:

  • forNameकक्षा में विधि Class
  • findSystemClassकक्षा में विधि ClassLoader
  • loadClassकक्षा में विधि ClassLoader

लेकिन निर्दिष्ट नाम के साथ वर्ग के लिए कोई परिभाषा नहीं मिली।

के लिए NoClassDefFoundError:

अगर जावा वर्चुअल मशीन या एक ClassLoaderउदाहरण एक वर्ग की परिभाषा में लोड करने की कोशिश करता है (सामान्य विधि कॉल के हिस्से के रूप में या नई अभिव्यक्ति का उपयोग करके एक नया उदाहरण बनाने के भाग के रूप में) और वर्ग की कोई परिभाषा नहीं मिल सकती है।

खोजे गए वर्ग की परिभाषा तब मौजूद थी जब वर्तमान में निष्पादित कक्षा संकलित की गई थी, लेकिन अब परिभाषा नहीं मिल सकती है।

तो, ऐसा प्रतीत होता है कि NoClassDefFoundErrorजब स्रोत सफलतापूर्वक संकलित किया गया था , तब होता है, लेकिन रनटाइम पर, आवश्यक classफाइलें नहीं मिलीं। यह कुछ ऐसा हो सकता है जो JAR फ़ाइलों के वितरण या उत्पादन में हो सकता है, जहां सभी आवश्यक classफाइलें शामिल नहीं थीं।

के रूप में ClassNotFoundException, ऐसा प्रतीत होता है कि यह रनटाइम में कक्षाओं के लिए चिंतनशील कॉल करने की कोशिश करने से स्टेम कर सकता है, लेकिन प्रोग्राम को कॉल करने की कोशिश कर रहे वर्गों का अस्तित्व नहीं है।

दोनों के बीच अंतर यह है कि एक एक है Errorऔर दूसरा एक है Exception। के साथ NoClassDefFoundErrorएक है Errorऔर यह जावा वर्चुअल मशीन से उत्पन्न होने वाली समस्याओं को खोजने के लिए एक वर्ग को खोजने में समस्याएं पैदा करता है। एक प्रोग्राम जिसे संकलन-समय पर काम करने की उम्मीद थी, वह classफाइलों के न मिलने के कारण नहीं चल सकता है, या ऐसा नहीं है जैसा कि कंपाइल-टाइम पर निर्मित या सामना किया गया था। यह एक बहुत महत्वपूर्ण त्रुटि है, क्योंकि कार्यक्रम को जेवीएम द्वारा शुरू नहीं किया जा सकता है।

दूसरी ओर, ClassNotFoundExceptionएक है Exception, इसलिए यह कुछ हद तक अपेक्षित है, और कुछ ऐसा है जो पुनर्प्राप्त करने योग्य है। परावर्तन का उपयोग त्रुटि-प्रवण हो सकता है (जैसा कि कुछ अपेक्षाएँ हैं कि चीजें अपेक्षा के अनुरूप नहीं हो सकती हैं। यह देखने के लिए कोई संकलन-समय की जांच नहीं है कि सभी आवश्यक कक्षाएं मौजूद हैं, इसलिए वांछित कक्षाएं ढूंढने के साथ कोई समस्या रनटाइम पर दिखाई देगी। ।


53
NoClassDefFoundErrorआम तौर पर तब होता है जब वर्ग के स्थैतिक ब्लॉक या स्थिर क्षेत्रों के साथ समस्या (अपवाद को फेंक दिया जाता है), इसलिए कक्षा को सफलतापूर्वक प्रारंभ नहीं किया जा सकता है।
Dagang

7
वोट दें। एक एक है Errorऔर दूसरा एक है Exception। :)
रवि

83

जब ClassLoader द्वारा रिपोर्ट की गई क्लास नहीं मिली तो ClassNotFoundException को फेंक दिया जाता है। इसका आम तौर पर मतलब है कि कक्षा CLASSPATH से गायब है। इसका अर्थ यह भी हो सकता है कि विचाराधीन वर्ग को किसी अन्य वर्ग से लोड करने की कोशिश की जा रही है जो कि एक पैरेंट क्लास लोडर में लोड किया गया था और इसलिए चाइल्ड क्लास लोडर से कक्षा दिखाई नहीं दे रही है। यह कभी-कभी ऐसा होता है जब ऐप सर्वर जैसे अधिक जटिल वातावरण में काम करना (WebSphere ऐसे क्लास लोडर मुद्दों के लिए बदनाम है)।

लोग अक्सर भ्रमित करने के लिए करते हैं java.lang.NoClassDefFoundErrorके साथ java.lang.ClassNotFoundExceptionलेकिन वहाँ एक महत्वपूर्ण अंतर है। उदाहरण के लिए एक अपवाद (चूंकि एक त्रुटि वास्तव java.lang.NoClassDefFoundErrorमें java.lang.Error का एक उपवर्ग है)

java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory

इसका मतलब यह नहीं है कि ActiveMQConnectionFactory वर्ग CLASSPATH में नहीं है। इसके बिल्कुल विपरीत प्रभाव। इसका मतलब यह है कि वर्ग ActiveMQConnectionFactory ClassLoader द्वारा पाया गया था, हालांकि जब कक्षा को लोड करने की कोशिश कर रहा था, तो यह कक्षा की परिभाषा को पढ़ने में एक त्रुटि में बदल गया। यह आमतौर पर तब होता है जब प्रश्न में वर्ग में स्थिर ब्लॉक या सदस्य होते हैं जो क्लास का उपयोग करते हैं जो क्लासऑलर द्वारा नहीं मिला है। इसलिए अपराधी को खोजने के लिए, प्रश्न में कक्षा के स्रोत को देखें (ActiveMQConnectionFactory इस मामले में) और स्थिर ब्लॉकों या स्थिर सदस्यों का उपयोग करके कोड की तलाश करें। यदि आपके पास स्रोत तक पहुंच नहीं है, तो बस इसे JAD का उपयोग करके विघटित कर दें।

कोड की जांच करने पर, आप कहते हैं कि आपको नीचे की तरह कोड की एक पंक्ति मिलती है, सुनिश्चित करें कि आपके CLASSPATH में कक्षा SomeClass।

private static SomeClass foo = new SomeClass();

युक्ति: यह पता लगाने के लिए कि कौन सा जार किस वर्ग का है, आप वेब साइट jarFinder का उपयोग कर सकते हैं। यह आपको वाइल्डकार्ड का उपयोग करके एक वर्ग नाम निर्दिष्ट करने की अनुमति देता है और यह अपने जार के डेटाबेस में वर्ग की खोज करता है। jarhoo आपको एक ही काम करने की अनुमति देता है लेकिन इसका अब उपयोग करने के लिए स्वतंत्र नहीं है।

यदि आप यह पता लगाना चाहते हैं कि एक स्थानीय पथ में कौन से जार का वर्ग है, तो आप jarscan ( http://www.inetfeedback.com/jarscan/ ) जैसी उपयोगिता का उपयोग कर सकते हैं । आप बस उस वर्ग को निर्दिष्ट करते हैं जिसे आप खोजना चाहते हैं और रूट निर्देशिका पथ है जहाँ आप यह चाहते हैं कि जार और ज़िप फ़ाइलों में कक्षा की खोज शुरू करें।


9
यह मजेदार है कि यह बिल्कुल सही उत्तर है जिसने अंतिम मतदान किया। (वोट देने से पहले भी -1)। ClassNotFoundException का अर्थ है CL .class फ़ाइल को नहीं देखता है। NoClassDefFoundError का अर्थ है .class फ़ाइल वहाँ लोड करने योग्य नहीं है (संभवतः JNI त्रुटि)।
user43685

1
क्या यह उत्तर उत्तर प्रपत्र कॉबर्ड के साथ विरोधाभासी नहीं है?
18

मैंने स्टैटिक ब्लॉक के समान उदाहरण की कोशिश की। मेरी कक्षा Class1 में स्थिर वैरिएबल है "निजी स्थिर B foo = new B ();" संकलन के बाद, मैंने बिन फ़ोल्डर से B.class फ़ाइल को हटा दिया। अब मैं तीसरी कक्षा की वस्तु बनाते हुए तीसरी कक्षा की मुख्य विधि से। रॉलर को फोल्वर्स के रूप में जाना जाता है: -------- "थ्रेड में अपवाद" मुख्य "java.lang.NoClassDefFoundError: स्प्रिंग / B" ........ तो यह बिल्कुल उल्लेख करता है कि यह किस क्लास में नहीं पाया गया ieclass स्थिर ब्लॉक में संदर्भित किया जाता है और बाहरी वर्ग नहीं। तो यह इस उत्तर के विपरीत है।
कौशिक लेले

+1 के बारे में स्पष्टीकरण के लिए "इसका मतलब यह नहीं है कि ActiveMQConnectionFactory वर्ग CLASSPATH में नहीं है"
akila

35

NoClassDefFoundErrorमूल रूप से एक लिंकेज त्रुटि है। यह तब होता है जब आप किसी ऑब्जेक्ट ("नए" के साथ सांख्यिकीय रूप से) को आज़माते हैं और इसे संकलित करते समय नहीं पाते हैं।

ClassNotFoundExceptionजब आप मौजूद वर्ग का उपयोग करने का प्रयास करते हैं तो अधिक सामान्य है और एक रनटाइम अपवाद है। उदाहरण के लिए, आपके पास एक फंक्शन में एक पैरामीटर है जो एक इंटरफ़ेस को स्वीकार करता है और कोई उस वर्ग में पास होता है जो उस इंटरफ़ेस को लागू करता है लेकिन आपके पास कक्षा तक पहुंच नहीं है। यह डायनामिक क्लास लोडिंग के मामले को भी कवर करता है, जैसे कि उपयोग करना loadClass()या Class.forName()


29

एक NoClassDefFoundError (NCDFE) तब होता है जब आपका कोड "नया Y ()" चलता है और यह Y वर्ग को नहीं खोज सकता है।

यह केवल यह हो सकता है कि Y आपके वर्ग लोडर से गायब है जैसे अन्य टिप्पणियां सुझाती हैं, लेकिन यह हो सकता है कि Y वर्ग पर हस्ताक्षर नहीं है या उसके पास एक अवैध हस्ताक्षर है, या कि Y आपके कोड को दिखाई नहीं दे रहा एक अलग वर्ग लोडर द्वारा लोड किया गया है , या यहां तक ​​कि वाई जेड पर निर्भर करता है जो उपरोक्त कारणों में से किसी के लिए लोड नहीं किया जा सकता है।

यदि ऐसा होता है, तो JVM को X (NCDFE) लोड करने का परिणाम याद होगा और यह हर बार एक नया NCDFE फेंकेगा, जब आप वाई से पूछेंगे कि आप यह क्यों कह रहे हैं:

कक्षा {
  स्थिर वर्ग b {}
  सार्वजनिक स्थैतिक शून्य main (String [] args[]) {
    System.out.println ("पहला प्रयास नया b ():");
    कोशिश {नया बी (); } पकड़ (फेंकने योग्य t) {t.printStackTrace ();}
    System.out.println ("\ n नया प्रयास नया b ():");
    कोशिश {नया बी (); } पकड़ (फेंकने योग्य t) {t.printStackTrace ();}
  }
}

इसे बचाने के लिए a.java कहीं

कोड बस एक नए "बी" वर्ग को दो बार पलटने की कोशिश करता है, इसके अलावा, इसमें कोई बग नहीं है, और यह कुछ भी नहीं करता है।

के साथ कोड संकलित करें javac a.java, फिर आह्वान करके चलाएं java -cp . a- यह केवल पाठ की दो पंक्तियों को प्रिंट करना चाहिए, और यह त्रुटियों के बिना ठीक चलना चाहिए।

फिर लापता या दूषित वर्ग को अनुकरण करने के लिए "एक $ b.class" फ़ाइल को हटा दें (या इसे कचरे से भर दें, या उस पर कॉपी करें)। यहाँ क्या होता है:

पहला प्रयास नया b ():
java.lang.NoClassDefFoundError: एक $ b
    a.main (a.java और) पर
इसके कारण: java.lang.ClassNotFoundException: a $ b
    java.net.URLClassLoader $ 1.run (URLClassLoader.java:200) पर
    java.security.AccessController.doPrivileged (मूल विधि) पर
    java.net.URLClassLoader.findClass (URLClassLoader.java:188) पर
    java.lang.ClassLoader.loadClass (ClassLoader.java:307) पर
    sun.misc.auncher पर $ AppClassLoader.loadClass (Launcher.java:301)
    java.lang.ClassLoader.loadClass (ClassLoader.java:252) पर
    java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320) पर
    ... 1 और

दूसरा प्रयास नया बी ():
java.lang.NoClassDefFoundError: एक $ b
    सुबह। (a.java:7)

पहली मंगलाचरण एक ClassNotFoundException (वर्ग लोडर द्वारा फेंका गया जब यह कक्षा नहीं पा सकता है), जिसे एक अनियंत्रित NoClassDefFoundError में लपेटा जाना चाहिए, क्योंकि प्रश्न में कोड ( new b()केवल काम करना चाहिए)।

दूसरा प्रयास निश्चित रूप से विफल भी होगा, लेकिन जैसा कि आप देख सकते हैं कि लिपटे अपवाद कोई और नहीं है, क्योंकि क्लासऑलर को विफल वर्ग लोडर याद है। आप केवल एनसीडीएफई को देखते हैं कि वास्तव में क्या हुआ है।

इसलिए यदि आपको कभी कोई NCDFE बिना किसी मूल कारण के दिखाई देता है, तो आपको यह देखने की आवश्यकता है कि क्या आप त्रुटि का कारण जानने के लिए कक्षा में पहली बार लोड किए गए थे।


-verboseविशिष्ट JVM के आधार पर JVM को चलाने के बारे में , या कुछ इसी तरह के विकल्प के बारे में क्या ? शायद -verbose:class, शायद -verbose:class:jniJNI का उपयोग करते हुए, लेकिन मैं वाक्य रचना के बारे में निश्चित नहीं हूं। यदि यह उपयोगी है, तो शायद आप परिणाम दिखा सकते हैं।
PJTraill

न तो -verbose:classहै और न ही -verbose:jniलापता वर्ग के लिए प्रासंगिक किसी भी अतिरिक्त उत्पादन दे।
मोगसी

1
यह कोशिश करने के लिए धन्यवाद, भले ही परिणाम निराशाजनक हो। (पी एस मैं के बाद से पता चला है कि -verbose:class:jniकुछ गड़बड़ है: एक दो अलग विकल्प निर्दिष्ट करने के लिए है -verbose:class -verbose:jni।)
PJTraill

2
अंतिम वाक्य * 1,000,000: तो अगर आपको कभी कोई मूल कारण के साथ NCDFE दिखाई देता है, तो आपको यह देखने की आवश्यकता है कि क्या आप त्रुटि के कारण का पता लगाने के लिए कक्षा में पहली बार लोड किए गए थे।
बैटवाड

20

से http://www.javaroots.com/2013/02/classnotfoundexception-vs.html :

ClassNotFoundException: तब होता है जब क्लास लोडर को क्लास पथ में आवश्यक क्लास नहीं मिल पाती है। तो, मूल रूप से आपको अपने वर्ग पथ की जांच करनी चाहिए और कक्षा को कक्षापथ में जोड़ना चाहिए।

NoClassDefFoundError: यह डिबग करना और कारण ढूंढना अधिक कठिन है। यह तब फेंक दिया जाता है जब संकलन के समय आवश्यक कक्षाएं मौजूद होती हैं, लेकिन रन समय में कक्षाएं बदल दी जाती हैं या हटा दी जाती हैं या कक्षा के स्थिर प्रारंभिक अपवादों को फेंक दिया जाता है। इसका मतलब है कि जो क्लास लोड हो रही है वह क्लासपाथ में मौजूद है, लेकिन इस क्लास के लिए जरूरी क्लास में से एक को कंपाइलर द्वारा लोड करने के लिए या तो हटा दिया जाता है या फेल कर दिया जाता है। इसलिए आपको उन वर्गों को देखना चाहिए जो इस वर्ग पर निर्भर हैं।

उदाहरण :

public class Test1
{
}


public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

अब दोनों वर्गों को संकलित करने के बाद, यदि आप Test1.class फ़ाइल को हटाते हैं और टेस्ट क्लास चलाते हैं, तो यह फेंक देगा

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more

ClassNotFoundException: जब कोई एप्लिकेशन अपने नाम के माध्यम से कक्षा में लोड करने का प्रयास करता है, तो फेंक दिया जाता है, लेकिन निर्दिष्ट नाम के साथ वर्ग के लिए कोई परिभाषा नहीं मिल सकती है।

NoClassDefFoundError: यदि जावा वर्चुअल मशीन एक वर्ग की परिभाषा में लोड करने की कोशिश करती है और कक्षा की कोई परिभाषा नहीं मिल सकती है तो फेंक दिया।


-verboseविशिष्ट JVM के आधार पर JVM को चलाने के बारे में , या कुछ इसी तरह के विकल्प के बारे में क्या ? शायद -verbose:class, शायद -verbose:class:jniJNI का उपयोग करते हुए, लेकिन मैं वाक्य रचना के बारे में निश्चित नहीं हूं।
PJTraill

-verbose:class:jniगलत है, लेकिन आप दो अलग-अलग विकल्प पास कर सकते हैं -verbose:class -verbose:jni:।
PJTraill

15

ऐसी त्रुटियों से निपटने के लिए उनमें से प्रत्येक और किसी भी विचार प्रक्रिया को प्राप्त करने का क्या कारण है?

वे बारीकी से संबंधित हैं। ए ClassNotFoundExceptionतब फेंका जाता है जब जावा नाम से एक विशेष वर्ग की तलाश करता है और इसे सफलतापूर्वक लोड नहीं कर सकता है। ए NoClassDefFoundErrorको तब फेंका जाता है जब जावा एक ऐसे वर्ग की तलाश में होता है जो कुछ मौजूदा कोड में जुड़ा हुआ था, लेकिन इसे एक कारण या किसी अन्य (जैसे, गलत क्लासपैथ, जावा का गलत संस्करण, एक पुस्तकालय का गलत संस्करण) के लिए नहीं मिल सका और पूरी तरह से घातक है जैसा कि यह इंगित करता है कि कुछ गलत तरीके से गलत हो गया है।

यदि आपको C बैकग्राउंड मिला है, तो CNFE विफलता की तरह है dlopen()/ dlsym()और NCDFE लिंकर के साथ एक समस्या है; दूसरे मामले में, संबंधित वर्ग की फ़ाइलों को वास्तव में उस कॉन्फ़िगरेशन में संकलित नहीं किया जाना चाहिए जिसे आप उनका उपयोग करने की कोशिश कर रहे हैं।


11

उदाहरण 1:

class A{
 void met(){
   Class.forName("com.example.Class1");
 }
}

यदि com/example/Class1किसी भी क्लासपैथ में मौजूद नहीं है, तो यह फेंकता हैClassNotFoundException

उदाहरण # 2:

Class B{
  void met(){
   com.example.Class2 c = new com.example.Class2();
 }
}

यदि com/example/Class2बी को संकलित करते समय अस्तित्व में था, लेकिन निष्पादन के दौरान नहीं मिला, तो यह फेंकता हैNoClassDefFoundError

दोनों को अपवाद के रूप में चलाया जाता है।


9

कक्षा में कोई भी अपवाद नही है को तब फेंका जाता है जब स्ट्रिंग के माध्यम से उसे संदर्भित करके कक्षा को लोड करने का प्रयास किया जाता है। उदाहरण के लिए Class.forName () में पैरामीटर एक स्ट्रिंग है, और यह अमान्य बाइनरी नामों को क्लासलोडर को दिए जाने की क्षमता को बढ़ाता है।

जब एक संभावित अमान्य बाइनरी नाम का सामना होता है, तो ClassNotFoundException को फेंक दिया जाता है; उदाहरण के लिए, यदि वर्ग नाम में '/' वर्ण है, तो आप ClassNotFoundException प्राप्त करने के लिए बाध्य हैं। यह तब भी फेंका जाता है जब सीधे संदर्भित क्लास क्लासपथ पर उपलब्ध नहीं होता है।

दूसरी ओर, NoClassDefFoundError को फेंक दिया जाता है

  • जब कक्षा का वास्तविक भौतिक प्रतिनिधित्व - .class फ़ाइल अनुपलब्ध हो,
  • या कक्षा को पहले से ही एक अलग क्लास लोडर में लोड किया गया है (आमतौर पर एक अभिभावक क्लास लोडर ने कक्षा को लोड किया होगा और इसलिए कक्षा को लोड नहीं किया जा सकता है),
  • या यदि कोई असंगत वर्ग परिभाषा पाई गई है - क्लास फ़ाइल में नाम अनुरोधित नाम से मेल नहीं खाता है,
  • या (सबसे महत्वपूर्ण बात) यदि एक आश्रित वर्ग को स्थित और लोड नहीं किया जा सकता है। इस स्थिति में, सीधे संदर्भित वर्ग स्थित और लोड हो सकता है, लेकिन निर्भर वर्ग उपलब्ध नहीं है या लोड नहीं किया जा सकता है। यह एक ऐसा परिदृश्य है जहाँ सीधे संदर्भित वर्ग को Class.forName या समकक्ष विधियों के माध्यम से लोड किया जा सकता है। यह लिंकेज में विफलता का संकेत देता है।

संक्षेप में, एक NoClassDefFoundError को आमतौर पर नए () स्टेटमेंट्स या मेथड इनवोकेशन पर फेंका जाता है, जो पहले अनुपस्थित क्लास को लोड करता है (क्लासगोटफ़ाउंड एक्ससेप्शन के लिए स्ट्रांग-बेस्ड लोडिंग क्लास के विपरीत), जब क्लास लोडर क्लास डेफिनेशन को खोजने या लोड करने में असमर्थ होता है ( रों)।

आखिरकार, यह ClassLader कार्यान्वयन तक है ClassNotFoundException के एक उदाहरण को फेंकने के लिए जब यह एक वर्ग को लोड करने में असमर्थ है। अधिकांश कस्टम क्लास लोडर कार्यान्वयन URLClassLoader का विस्तार करने के बाद से यह प्रदर्शन करते हैं। आमतौर पर क्लास लोडर स्पष्ट रूप से किसी भी विधि कार्यान्वयन पर NoClassDefFoundError को नहीं फेंकते हैं - यह अपवाद आमतौर पर हॉटस्पॉट कंपाइलर में जेवीएम से फेंका जाता है, और केवल क्लास लोडर द्वारा नहीं।


'क्लास फाइल में नाम मांगे गए नाम से मेल नहीं खाता' का उल्लेख करने के लिए अपवोट करें। यह काफी सामान्य कारण है।
लोर्ने

8

ClassNotFoundException बनाम NoClassDefFoundError के बीच अंतर

यहां छवि विवरण दर्ज करें


क्रिस्टल स्पष्ट नहीं। "क्लासपाथ में अद्यतन नहीं" अस्पष्ट / अभेद्य है। यह या तो JAR को क्लासपाथ में मौजूद नहीं होने के बारे में है, या JAR के क्लासपाथ पर होने के गलत संस्करण के बारे में है। और वर्तनी की त्रुटियाँ। और (आह) चूंकि आपने अपनी जानकारी को एक कायरता ग्राफिक के रूप में पोस्ट किया है, इसलिए हम इसे ठीक नहीं कर सकते।
स्टीफन सी

8

नामों से ही हम आसानी से एक की पहचान कर सकते हैं Exceptionऔर दूसरे से Error

अपवाद: अपवाद कार्यक्रम के निष्पादन के दौरान होता है। एक प्रोग्रामर इन कैच ब्लॉक को आज़माकर इन अपवादों को संभाल सकता है। हमारे पास दो प्रकार के अपवाद हैं। संकलित अपवाद जो संकलन समय पर फेंकता है। रनटाइम अपवाद जो रन टाइम पर फेंके जाते हैं, ये अपवाद आमतौर पर खराब प्रोग्रामिंग के कारण होते हैं।

त्रुटि: ये अपवाद नहीं हैं, यह प्रोग्रामर के दायरे से परे है। ये त्रुटियां आमतौर पर जेवीएम द्वारा डाली जाती हैं।


यहां छवि विवरण दर्ज करें छवि स्रोत

अंतर:

कक्षा में कोई भी अपवाद नही है:

  • कक्षा लोडर में विफल रहता है की पुष्टि एक वर्ग बाइट कोड हम में उल्लेख लिंक चरण के वर्ग लोड हो रहा है सबसिस्टम पर हम पाते हैं ClassNotFoundException
  • ClassNotFoundExceptionएक जाँच अपवाद है जो सीधे java.lang.Exceptionवर्ग से प्राप्त होता है और आपको इसके लिए स्पष्ट हैंडलिंग प्रदान करने की आवश्यकता होती है
  • ClassNotFoundExceptionतब आता है जब ClassLoader.loadClass (), Class.forName () और ClassLoader.findSystemClass () का उपयोग करके रनटाइम पर कक्षा का नाम प्रदान करके कक्षा का एक स्पष्ट लोड होता है।

कक्षा डेफ में कोई त्रुटि नहीं मिली:

  • कक्षा लोडर में विफल रहता है को हल करने में एक वर्ग के संदर्भ लिंक चरण के वर्ग लोड हो रहा है सबसिस्टम पर हम पाते हैं NoClassDefFoundError
  • NoClassDefFoundErrorLinkageErrorवर्ग से प्राप्त एक त्रुटि है , जिसका उपयोग त्रुटि मामलों को इंगित करने के लिए किया जाता है, जहां एक वर्ग की किसी अन्य कक्षा पर निर्भरता होती है और संकलन के बाद उस वर्ग को असंगत रूप से बदल दिया जाता है।
  • NoClassDefFoundErrorक्लास के निहित लोडिंग का एक परिणाम है क्योंकि उस क्लास या किसी वैरिएबल एक्सेस से एक विधि कॉल है।

समानता:

  • दोनों NoClassDefFoundErrorऔरClassNotFoundException रन-टाइम में एक वर्ग की अनुपलब्धता से संबंधित हैं।
  • दोनों ClassNotFoundExceptionऔर NoClassDefFoundErrorजावा classpath से संबंधित हैं।

3

कक्षा लोडर sussystem कार्यों को देखते हुए:

http://www.artima.com/insidejvm/ed2/images/fig7-1.gif

यह एक लेख है जिसने मुझे अंतर को समझने में बहुत मदद की: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

यदि क्लास लोडिंग के दौरान कोई त्रुटि होती है, तो लिंकेज के एक उपवर्ग का एक उदाहरण प्रोग्राम में एक बिंदु पर फेंक दिया जाना चाहिए जो (प्रत्यक्ष या अप्रत्यक्ष रूप से) क्लास या इंटरफ़ेस को लोड किए जाने का उपयोग करता है।

यदि जावा वर्चुअल मशीन कभी भी सत्यापन (Java5.4.1) या रिज़ॉल्यूशन (§5.4.3) (लेकिन आरंभीकरण (.55.5)) के दौरान क्लास सी लोड करने का प्रयास नहीं करती है, और सी लोडिंग शुरू करने के लिए उपयोग किया जाने वाला क्लास लोडर ClassNotFoundException का एक उदाहरण फेंकता है , तो Java वर्चुअल मशीन को NoClassDefFoundError का एक उदाहरण फेंकना चाहिए, जिसका कारण ClassNotFoundException का उदाहरण है ।

तो एक ClassNotFoundException NoClassDefFoundError का मूल कारण है ।
और एक NoClassDefFoundError एक विशेष प्रकार की लोडिंग त्रुटि है, जो लिंकिंग चरण में होती है ।


2

व्यवहार में एक संभावित कारण जोड़ें:

  • ClassNotFoundException: जैसा कि cletus ने कहा था, आप इंटरफ़ेस का उपयोग करते हैं जबकि इनहेरिट की गई क्लास क्लासपैथ में नहीं होती है। जैसे, सेवा प्रदाता पैटर्न (या सेवा लोकेटर ) कुछ गैर-मौजूदा वर्ग का पता लगाने की कोशिश करता है
  • NoClassDefFoundError: दी गई कक्षा पाई जाती है, जबकि दिए गए वर्ग की निर्भरता नहीं पाई जाती है

व्यवहार में, त्रुटि को चुपचाप फेंक दिया जा सकता है , उदाहरण के लिए, आप एक टाइमर कार्य प्रस्तुत करते हैं और टाइमर कार्य में यह त्रुटि फेंकता है , जबकि ज्यादातर मामलों में, आपका कार्यक्रम केवल अपवाद को पकड़ता है । फिर टाइमर का मुख्य लूप बिना किसी जानकारी के समाप्त हो जाता है। NoClassDefFoundError में एक समान त्रुटि ExceptionInInitializerError है , जब आपका स्टैटिक इनिशियलाइज़र या स्टैटिकलाइज़र एक वैरिएबल वैरिएबल अपवाद को फेंकता है।


1

ClassNotFoundException एक चेक किया गया अपवाद है जो तब होता है जब हम JVM को Class.forName () या ClassLoader.findSystemClass () या ClassLoader.loadClass () विधियों का उपयोग करके एक क्लास को लोड करने के लिए कहते हैं और क्लास में क्लाथ में पाया नहीं गया है।

अधिकांश समय, यह अपवाद तब होता है जब आप आवश्यक JAR फ़ाइलों के साथ classpath को अपडेट किए बिना किसी एप्लिकेशन को चलाने का प्रयास करते हैं। उदाहरण के लिए, आपने JDBC कोड को अपने डेटाबेस से कनेक्ट करने के लिए यह अपवाद देखा होगा।

NoClassDefFoundError त्रुटि तब होती है जब JVM एक विशेष वर्ग को लोड करने की कोशिश करता है जो आपके कोड निष्पादन (सामान्य विधि कॉल के हिस्से के रूप में या नए कीवर्ड का उपयोग करके एक उदाहरण बनाने के भाग के रूप में) का हिस्सा है और वह वर्ग आपके classpath में मौजूद नहीं है लेकिन था संकलित समय पर उपस्थित क्योंकि आपके कार्यक्रम को निष्पादित करने के लिए आपको इसे संकलित करने की आवश्यकता है और यदि आप एक वर्ग का उपयोग करने का प्रयास कर रहे हैं जो संकलक मौजूद नहीं है तो संकलन त्रुटि को बढ़ाएगा।

नीचे संक्षिप्त विवरण दिया गया है

यहां छवि विवरण दर्ज करें

आप अधिक विवरण के लिए ClassNotFoundException Vs NoClassDefFoundError के बारे में सब कुछ पढ़ सकते हैं ।


0

जब भी मुझे रिफ्रेश करने की आवश्यकता होती है, मैं खुद को बार-बार निम्नलिखित की याद दिलाता हूं

कक्षा में कोई भी अपवाद नही है

कक्षा पदानुक्रम

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

डिबगिंग करते समय

  1. आवश्यक जार, क्लास क्लासपथ से गायब है।
  2. सत्यापित करें कि सभी आवश्यक जार jvm के वर्गपथ में हैं।

कक्षा डेफ में कोई त्रुटि नहीं मिली

कक्षा पदानुक्रम

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

डिबगिंग करते समय

  1. एक कक्षा को गतिशील रूप से लोड करने में समस्या, जिसे ठीक से संकलित किया गया था
  2. स्थिर ब्लॉकों, कंस्ट्रक्टर्स, इनिट (आश्रित वर्ग के तरीकों) और वास्तविक त्रुटि के साथ समस्या कई परतों द्वारा लपेटी जाती है [विशेषकर जब आप वसंत का उपयोग करते हैं, तो वास्तविक अपवाद को हाइबरनेट किया जाता है और आपको NoClassDefError मिल जाएगी]
  3. जब आप "ClassNotFoundException" का सामना करते हैं, तो आश्रित वर्ग के एक स्थिर ब्लॉक के तहत
  4. कक्षा के संस्करणों के साथ समस्या। ऐसा तब होता है जब आपके पास अलग-अलग जार / पैकेज के तहत एक ही वर्ग के दो संस्करण v1, v2 होते हैं, जो कि v1 का उपयोग करके सफलतापूर्वक संकलित किया गया था और v2 को रनटाइम पर लोड किया गया है जिसमें प्रासंगिक विधियाँ / संस्करण नहीं हैं और आपको यह अपवाद दिखाई देगा। [मैंने एक बार क्लासपैथ में दिखाई देने वाले कई जार के तहत लॉग 4j संबंधित वर्ग के डुप्लिकेट को हटाकर इस मुद्दे को हल किया]

-1

ClassNotFoundException और NoClassDefFoundError तब होती है जब कोई विशेष वर्ग रनटाइम पर नहीं मिलता है। फिर भी, वे विभिन्न परिदृश्यों में होते हैं।

ClassNotFoundException एक अपवाद है जो तब होती है जब आप Class.forName () या loadClass () विधियों का उपयोग करके रन टाइम पर क्लास लोड करने का प्रयास करते हैं और उल्लिखित क्लासेस क्लासपैथ में नहीं पाए जाते हैं।

    public class MainClass
    {
        public static void main(String[] args)
        {
            try
            {
                Class.forName("oracle.jdbc.driver.OracleDriver");
            }catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }
        }
    }



    java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at pack1.MainClass.main(MainClass.java:17)

NoClassDefFoundError एक त्रुटि है जो तब होती है जब कोई विशेष वर्ग संकलित समय पर मौजूद होता है, लेकिन रन समय पर अनुपलब्ध था।

    class A
    {
      // some code
    }
    public class B
    {
        public static void main(String[] args)
        {
            A a = new A();
        }
    }

जब आप उपरोक्त कार्यक्रम संकलित करते हैं, तो दो .class फाइलें उत्पन्न होंगी। एक अक्लास है और दूसरा बक्लास है। यदि आप A.class फ़ाइल को हटाते हैं और B.class फ़ाइल को चलाते हैं, तो Java रनटाइम सिस्टम नीचे की तरह NoClassDefFoundError फेंक देगा:

    Exception in thread "main" java.lang.NoClassDefFoundError: A
    at MainClass.main(MainClass.java:10)
    Caused by: java.lang.ClassNotFoundException: A
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.