NoClassDefFoundError
जब मैं अपना जावा एप्लिकेशन चलाता हूं तो मुझे मिल रहा है। आमतौर पर इसका कारण क्या है?
NoClassDefFoundError
जब मैं अपना जावा एप्लिकेशन चलाता हूं तो मुझे मिल रहा है। आमतौर पर इसका कारण क्या है?
जवाबों:
ऐसा तब होता है जब कोई क्लास फ़ाइल होती है जो आपके कोड पर निर्भर करती है और यह संकलन समय पर मौजूद है लेकिन रनटाइम पर नहीं मिली है। अपने निर्माण समय और रनटाइम क्लासपैथ में अंतर देखें।
हालांकि यह संभव है कि यह संकलन-समय और रन-टाइम के बीच एक क्लासपैथ बेमेल के कारण है, यह जरूरी नहीं कि सच है।
इस मामले में दो या तीन अलग-अलग अपवादों को सीधे हमारे सिर पर रखना महत्वपूर्ण है:
java.lang.ClassNotFoundException
यह अपवाद इंगित करता है कि कक्षा को क्लासपाथ पर नहीं मिला था। यह इंगित करता है कि हम कक्षा की परिभाषा को लोड करने की कोशिश कर रहे थे, और कक्षा में क्लासपैथ मौजूद नहीं था।
java.lang.NoClassDefFoundError
यह अपवाद इंगित करता है कि JVM ने अपने आंतरिक वर्ग परिभाषा डेटा संरचना में एक वर्ग की परिभाषा के लिए देखा और इसे नहीं पाया। यह कहने से अलग है कि इसे क्लासपाथ से लोड नहीं किया जा सकता था। आमतौर पर यह इंगित करता है कि हमने पहले क्लासपाथ से एक कक्षा को लोड करने का प्रयास किया था, लेकिन यह किसी कारण से विफल हो गया - अब हम फिर से कक्षा का उपयोग करने की कोशिश कर रहे हैं (और इसलिए इसे लोड करने की आवश्यकता है, क्योंकि यह पिछली बार विफल हुआ था), लेकिन हम ' फिर भी इसे लोड करने की कोशिश नहीं की जाएगी, क्योंकि हम इसे पहले लोड करने में विफल रहे (और यथोचित संदेह है कि हम फिर से विफल हो जाएंगे)। पहले की विफलता एक ClassNotFoundException या ExceptionInInitializerError (स्थैतिक आरंभीकरण ब्लॉक में विफलता का संकेत) या किसी भी अन्य समस्या हो सकती है। मुद्दा यह है कि, एक NoClassDefFoundError जरूरी एक classpath समस्या नहीं है।
Error: Could not find or load main class
, तो इसे किस श्रेणी की त्रुटि के तहत वर्गीकृत किया जाएगा?
यहाँ उदाहरण के लिए कोड है java.lang.NoClassDefFoundError
। कृपया विस्तृत विवरण के लिए जेरेड का उत्तर देखें ।
NoClassDefFoundErrorDemo.java
public class NoClassDefFoundErrorDemo {
public static void main(String[] args) {
try {
// The following line would throw ExceptionInInitializerError
SimpleCalculator calculator1 = new SimpleCalculator();
} catch (Throwable t) {
System.out.println(t);
}
// The following line would cause NoClassDefFoundError
SimpleCalculator calculator2 = new SimpleCalculator();
}
}
SimpleCalculator.java
public class SimpleCalculator {
static int undefined = 1 / 0;
}
SimpleCalculator
शून्य से विभाजित होने के बाद असफल वर्ग की तुलना में कहीं संग्रहीत है ? क्या किसी के पास इस व्यवहार के लिए आधिकारिक दस्तावेज का संदर्भ है?
new SimpleCalculator()
कहा जाता है, आपको ArithmeticException की वजह से ExceptionInInitializerError मिलता है। दूसरी बार जब आप कॉल new SimpleCalculator()
करते हैं तो आपको NoClassDefFoundError किसी अन्य की तरह शुद्ध मिलती है। मुद्दा यह है कि आप साधारण कारण के अलावा एक कारण के लिए एक NoClassDefFoundError प्राप्त कर सकते हैं। रनटाइम पर क्लासपैथ पर नहीं होने के कारण।
जावा में NoClassDefFoundError
परिभाषा:
जावा वर्चुअल मशीन रनटाइम पर एक विशेष वर्ग को खोजने में सक्षम नहीं है जो संकलन समय पर उपलब्ध था।
यदि कोई वर्ग संकलन समय के दौरान मौजूद था, लेकिन रनवे के दौरान जावा क्लासपथ में उपलब्ध नहीं था।
उदाहरण:
NoClassDefFoundError का एक सरल उदाहरण है क्लास एक लापता JAR फ़ाइल से संबंधित है या JAR को क्लासपाथ में नहीं जोड़ा गया था या कभी-कभी जार का नाम किसी के द्वारा बदल दिया गया था जैसे मेरे मामले में मेरे एक सहयोगी ने tibco.jar को tibco_v3.jar में बदल दिया है और कार्यक्रम है java.lang.NoClassDefFoundError के साथ असफल होना और मैं सोच रहा था कि क्या गलत है।
बस स्पष्ट रूप से-क्लासपास विकल्प के साथ चलने की कोशिश करें जो आपको लगता है कि क्लासपाथ के साथ काम करेगा और यदि यह काम कर रहा है तो यह एक निश्चित छोटा संकेत है कि कोई व्यक्ति जावा क्लासपथ से आगे निकल रहा है।
संभव समाधान:
संसाधन:
मैंने पाया है कि कभी-कभी मुझे एक NoClassDefFound त्रुटि मिलती है जब कोड रनटाइम पर पाए जाने वाले वर्ग के असंगत संस्करण के साथ संकलित किया जाता है। मुझे याद है कि विशिष्ट उदाहरण अपाचे अक्ष पुस्तकालय के साथ है। मेरे रनटाइम क्लासपाथ पर वास्तव में 2 संस्करण थे और यह तारीख और असंगत संस्करण को बाहर निकाल रहा था और सही नहीं था, जिसके कारण NoClassDefFound त्रुटि हुई। यह एक कमांड लाइन ऐप में था जहां मैं इसके समान कमांड का उपयोग कर रहा था।
set classpath=%classpath%;axis.jar
मैं इसका उपयोग करके उचित संस्करण लेने में सक्षम था:
set classpath=axis.jar;%classpath%;
यह मेरा अब तक का सबसे अच्छा समाधान है ।
मान लीजिए कि हमारे पास एक पैकेज है जिसे org.mypackage
कक्षाएं शामिल हैं:
और इस पैकेज को परिभाषित करने वाली फाइलें भौतिक रूप से निर्देशिका के तहत D:\myprogram
(विंडोज पर) या /home/user/myprogram
लिनक्स पर संग्रहीत की जाती हैं ।
फ़ाइल संरचना इस तरह दिखाई देगी:
जब हम जावा को लागू करते हैं, तो हम चलाने के लिए एप्लिकेशन का नाम निर्दिष्ट करते हैं org.mypackage.HelloWorld
:। हालाँकि हमें जावा को यह भी बताना चाहिए कि हमारे पैकेज को परिभाषित करने वाली फ़ाइलों और निर्देशिकाओं को कहाँ देखना है। इसलिए प्रोग्राम को लॉन्च करने के लिए, हमें निम्नलिखित कमांड का उपयोग करना होगा:
मैं मावेन के साथ स्प्रिंग फ्रेमवर्क का उपयोग कर रहा था और अपनी परियोजना में इस त्रुटि को हल किया।
कक्षा में एक रनटाइम त्रुटि थी। मैं एक संपत्ति को पूर्णांक के रूप में पढ़ रहा था, लेकिन जब उसने संपत्ति फ़ाइल से मूल्य पढ़ा, तो उसका मूल्य दोगुना था।
स्प्रिंग ने मुझे एक पूर्ण स्टैक ट्रेस नहीं दिया, जिस पर रनटाइम विफल हुआ। यह बस कहा NoClassDefFoundError
। लेकिन जब मैंने इसे एक देशी जावा एप्लिकेशन (एमवीसी से बाहर ले जाना) के रूप में निष्पादित किया, तो इसने दिया ExceptionInInitializerError
जो सही कारण था और इस तरह मैंने त्रुटि का पता लगाया।
@ xli के जवाब ने मुझे जानकारी दी कि मेरे कोड में क्या गलत हो सकता है।
NoClassDefFoundError
था ( वास्तव में इसके कारण था ExceptionInInitalizerError
, जो इसके कारण था DateTimeParseException
)। यह थोड़ा भ्रामक है, है ना? मुझे पता है कि उनके पास शायद इसे बनाने के लिए उनके कारण थे, लेकिन कम से कम एक छोटा संकेत होना बहुत अच्छा होगा, यह NoClassDefFoundError
एक और अपवाद का परिणाम था, बिना इसे घटाए। बस ExceptionInInitializerError
फिर से फेंकना अधिक स्पष्ट होगा। कभी-कभी दोनों के बीच संबंध स्पष्ट नहीं हो सकता है।
मुझे NoClassFoundError मिलता है जब रनटाइम क्लास लोडर द्वारा लोड की गई कक्षाएं जावा रूट लोडर द्वारा पहले से लोड की गई कक्षाओं तक नहीं पहुंच सकती हैं। क्योंकि अलग-अलग श्रेणी लोडर अलग-अलग सुरक्षा डोमेन (जावा के अनुसार) में होते हैं, jvm रनटाइम लोडर एड्रेस स्पेस में रूट लोडर द्वारा पहले से लोड की गई कक्षाओं को हल करने की अनुमति नहीं देगा।
'Java -javaagent: tracer.jar [आपका java ARGS]' के साथ अपना कार्यक्रम चलाएं
यह लोडेड क्लास, और लोडर env को दिखाता है जो क्लास को लोड करता है। यह बहुत उपयोगी है क्यों एक वर्ग हल नहीं किया जा सकता है।
// ClassLoaderTracer.java
// From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5
import java.lang.instrument.*;
import java.security.*;
// manifest.mf
// Premain-Class: ClassLoadTracer
// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class
// java -javaagent:tracer.jar [...]
public class ClassLoadTracer
{
public static void premain(String agentArgs, Instrumentation inst)
{
final java.io.PrintStream out = System.out;
inst.addTransformer(new ClassFileTransformer() {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);
// dump stack trace of the thread loading class
Thread.dumpStack();
// we just want the original .class bytes to be loaded!
// we are not instrumenting it...
return null;
}
});
}
}
एक दिलचस्प मामला जिसमें आप बहुत कुछ देख सकते हैं NoClassDefFoundErrors
जब आप हैं:
throw
एक RuntimeException
में static
अपने वर्ग के ब्लॉकExample
Example
static class Example {
static {
thisThrowsRuntimeException();
}
}
static class OuterClazz {
OuterClazz() {
try {
new Example();
} catch (Throwable ignored) { //simulating catching RuntimeException from static block
// DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
}
new Example(); //this throws NoClassDefFoundError
}
}
NoClassDefError
ExceptionInInitializerError
स्थैतिक ब्लॉक के साथ फेंक दिया जाएगा RuntimeException
।
यह विशेष रूप से महत्वपूर्ण मामला है जब आप NoClassDefFoundErrors
अपने UNIT TESTS में देखते हैं ।
एक तरह से आप static
परीक्षणों के बीच ब्लॉक निष्पादन को "साझा" कर रहे हैं , लेकिन प्रारंभिक ExceptionInInitializerError
केवल एक परीक्षण मामले में होगा। पहला वह जो समस्याग्रस्त Example
वर्ग का उपयोग करता है । अन्य परीक्षण मामले जो Example
कक्षा का उपयोग करते हैं, वे सिर्फ फेंक देंगे NoClassDefFoundErrors
।
नीचे दी गई तकनीक ने मुझे कई बार मदद की:
System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());
जहां TheNoDefFoundClass वह वर्ग है जो आपके प्रोग्राम द्वारा उपयोग किए गए समान लाइब्रेरी के पुराने संस्करण के लिए वरीयता के कारण "खो" हो सकता है। यह सबसे अधिक बार मामलों के साथ होता है, जब क्लाइंट सॉफ़्टवेयर को एक प्रमुख कंटेनर में तैनात किया जाता है, जो अपने स्वयं के क्लास लोडर और सबसे लोकप्रिय कामों के प्राचीन संस्करणों के टन से लैस होता है।
यदि आपके पास जनरेट-कोड (EMF, आदि) है तो बहुत सारे स्टैटिक इनिशियलाइज़र हो सकते हैं जो सभी स्टैक स्पेस का उपभोग करते हैं।
स्टैक ओवरफ्लो प्रश्न देखें जावा स्टैक आकार कैसे बढ़ाएं? ।
NoClassDefFoundError
तब भी हो सकता है जब कोई स्थैतिक इनिलाइज़र एक संसाधन बंडल लोड करने का प्रयास करता है जो रनटाइम में उपलब्ध नहीं होता है, उदाहरण के लिए एक गुण फ़ाइल जिसे प्रभावित वर्ग META-INF
निर्देशिका से लोड करने का प्रयास करता है , लेकिन ऐसा नहीं है। यदि आप नहीं पकड़ते हैं NoClassDefFoundError
, तो कभी-कभी आप पूर्ण स्टैक ट्रेस नहीं देख पाएंगे; इसे दूर करने के लिए आप अस्थायी रूप से एक catch
क्लॉज का उपयोग कर सकते हैं Throwable
:
try {
// Statement(s) that cause the affected class to be loaded
} catch (Throwable t) {
Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}
for example a properties file that the affected class tries to load from the META-INF directory
। यह वास्तव में मेरे साथ हुआ है और मैं NoClassDefFoundError
लापता गुण फ़ाइल को जोड़कर हल करने में सक्षम था । मैंने इस उत्तर को ठीक से जोड़ा क्योंकि कोई इस त्रुटि का उल्लेख परिस्थितियों में नहीं करेगा।
static
प्रारंभ में लोड करने का प्रयास कर रहे हैं ... जो एक अनियंत्रित अपवाद को ट्रिगर करता है और कक्षा का कारण बनता है। असफल होना। स्थैतिक आरंभीकरण से उत्पन्न कोई भी अनियंत्रित अपवाद ऐसा करेगा।
static
आरंभीकरण के कारण नहीं है), तो मैं एक वास्तविक उदाहरण (यानी MCVE) देखना चाहूंगा जो व्यवहार को प्रदर्शित करता हो।
मुझे यह त्रुटि तब हुई जब मैं अपने प्रोजेक्ट में एक अन्य मॉड्यूल की मावेन निर्भरता को जोड़ता हूं, इस मुद्दे को अंततः -Xss2m
मेरे कार्यक्रम के जेवीएम विकल्प (यह जेडीके 5.0 के बाद से डिफ़ॉल्ट रूप से एक मेगाबाइट है) में जोड़कर हल किया गया था । यह माना जाता है कि कार्यक्रम में कक्षा को लोड करने के लिए पर्याप्त स्टैक नहीं है।
यदि कोई java.lang.NoClassDefFoundError: org/apache/log4j/Logger
त्रुटि के कारण यहां आता है , तो मेरे मामले में इसका उत्पादन किया गया था क्योंकि मैंने log4j 2 का उपयोग किया था (लेकिन मैंने इसके साथ आने वाली सभी फ़ाइलों को नहीं जोड़ा था), और कुछ निर्भरता लाइब्रेरी ने log4j का उपयोग किया था। 1 समाधान Log4j को जोड़ने के लिए था 1.x ब्रिज: जार log4j-1.2-api-<version>.jar
जो log4j के साथ आता है 2. log4j 2 माइग्रेशन में अधिक जानकारी ।
मेरे मामले में, समस्या एक ही परियोजना की दो अलग-अलग प्रतियों के बीच अंतर करने में ग्रहण की अक्षमता थी। मेरे पास एक ट्रंक (एसवीएन संस्करण नियंत्रण) पर लॉक है और दूसरा एक समय में एक शाखा में काम कर रहा है। मैंने JUnit परीक्षण मामले के रूप में कार्य प्रतिलिपि में एक बदलाव की कोशिश की, जिसमें एक निजी आंतरिक वर्ग को अपने आप पर एक सार्वजनिक वर्ग निकालने के लिए शामिल किया गया था और जब यह काम कर रहा था, तो मैंने इस परियोजना की अन्य प्रतिलिपि को किसी अन्य के आसपास देखने के लिए खोल दिया उस कोड का हिस्सा जिसमें बदलाव की जरूरत थी। कुछ बिंदु पर,NoClassDefFoundError
शिकायत करते हुए कि निजी आंतरिक वर्ग वहां नहीं था; स्टैक ट्रेस में डबल-क्लिक करने से मुझे गलत प्रोजेक्ट कॉपी में स्रोत फ़ाइल में लाया गया।
परियोजना की ट्रंक कॉपी को बंद करना और परीक्षण मामले को फिर से चलाने से समस्या से छुटकारा मिला।
यह त्रुटि अनियंत्रित जावा संस्करण आवश्यकताओं के कारण हो सकती है ।
मेरे मामले में मैं एसडीकेमैन का उपयोग करके जावा 9 से जावा 8 पर स्विच करके, एक हाई-प्रोफाइल ओपन-सोर्स प्रोजेक्ट का निर्माण करते हुए, इस त्रुटि को हल करने में सक्षम था ! ।
sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu
फिर नीचे वर्णित के रूप में एक साफ स्थापित कर रहा है।
अपने निर्माण उपकरण के रूप में मावेन का उपयोग करते समय , यह कभी-कभी मददगार होता है - और आम तौर पर संतुष्टिदायक, एक साफ 'इंस्टॉल' निर्माण करने के लिए परीक्षण अक्षम के साथ ।
mvn clean install -DskipTests
अब जब सब कुछ बनाया और स्थापित किया गया है, तो आप आगे बढ़ सकते हैं और परीक्षण चला सकते हैं।
mvn test
जब मुझे मेरे प्रोजेक्ट के जावा बिल्ड पाथ में "ऑर्डर और एक्सपोर्ट" टैब पर एक क्लास निर्यात नहीं किया गया तो मुझे NoClassDefFound त्रुटियाँ मिलीं। प्रोजेक्ट के निर्माण पथ में आपके द्वारा जोड़ी गई किसी भी निर्भरता के "ऑर्डर और निर्यात" टैब में एक चेकमार्क डालना सुनिश्चित करें। ग्रहण चेतावनी देखें : XXXXXXXXXXXXX.jar को निर्यात या प्रकाशित नहीं किया जाएगा। रनटाइम ClassNotFoundException परिणाम हो सकता है ।
मेरे मामले में मुझे यह त्रुटि JDK संस्करणों में एक बेमेल के कारण मिल रही थी। जब मैंने Intelij से एप्लिकेशन को चलाने की कोशिश की तो यह काम नहीं कर रहा था लेकिन फिर कमांड लाइन से इसे चलाने पर काम हुआ। ऐसा इसलिए है क्योंकि Intelij इसे Java 11 JDK के साथ चलाने का प्रयास कर रहा था जो सेटअप था लेकिन कमांड लाइन पर यह Java 8 JDK के साथ चल रहा था। फ़ाइल> प्रोजेक्ट स्ट्रक्चर> प्रोजेक्ट सेटिंग्स> प्रोजेक्ट एसडीके के तहत उस सेटिंग को स्विच करने के बाद, इसने मेरे लिए काम किया।
हर कोई यहाँ कुछ जावा विन्यास सामान, जेवीएम समस्याओं आदि के बारे में बात करता है, मेरे मामले में त्रुटि इन विषयों से संबंधित नहीं थी और कारण को हल करने के लिए बहुत तुच्छ और आसान था: मेरे नियंत्रक में मेरे समापन बिंदु पर एक गलत टिप्पणी थी ( स्प्रिंग बूट आवेदन)।
मुझे लिबर्टी सर्वर के साथ काम करने वाले JavaEE में NoClassDefFoundError के साथ एक दिलचस्प मुद्दा मिला है। मैं IMS संसाधन एडेप्टर का उपयोग कर रहा था और मेरे सर्वर.xml में पहले से ही imsudbJXA.rar के लिए संसाधन एडॉप्टर था। जब मैंने imsudbXA.rar के लिए नया एडेप्टर जोड़ा, तो मुझे यह त्रुटि DLIException, IMSConnectionSpec या SQLInteractionSpec के लिए ऑब्जेक्ट ऑब्जेक्ट के लिए मिलनी शुरू हो जाएगी। मैं समझ नहीं पाया कि मैंने केवल imsudbXA.rar का उपयोग करके अपने काम के लिए नया सर्वर.xml बनाकर इसे हल क्यों किया। मुझे यकीन है कि server.xml में कई संसाधन एडेप्टर का उपयोग करना ठीक है, मेरे पास उस पर गौर करने का कोई समय नहीं था।
जावा को रनटाइम में क्लास ए नहीं मिल रहा था। क्लास ए एक अलग कार्यक्षेत्र से मावेन प्रोजेक्ट आर्टक्लाइंट में था। इसलिए मैंने अपने ग्रहण प्रोजेक्ट में ArtClient को आयात किया। मेरी दो परियोजनाएं ArtClient का उपयोग निर्भरता के रूप में कर रही थीं। मैंने इन लोगों के लिए प्रोजेक्ट रेफरेंस में लाइब्रेरी रेफरेंस (बिल्ड पाथ -> कॉन्फिगर बिल्ड पाथ) को बदल दिया।
और समस्या दूर हो गई।
मुझे यह संदेश SRC लाइब्रेरी से दो फ़ाइलों को हटाने के बाद मिला है, और जब मैं उन्हें वापस लाया तो मैं इस त्रुटि संदेश को देखता रहा।
मेरा समाधान था: ग्रहण को फिर से शुरू करना। तब से मैंने यह संदेश दोबारा नहीं देखा है :-)
यह सुनिश्चित करें कि यह module:app
और module:lib
:
android {
compileSdkVersion 23
buildToolsVersion '22.0.1'
packagingOptions {
}
defaultConfig {
minSdkVersion 17
targetSdkVersion 23
versionCode 11
versionName "2.1"
}
{s
और दो }
)। क्या आप इसे ठीक कर सकते हैं?