ทำไมฉันถึงได้รับ NoClassDefFoundError ใน Java


530

ฉันได้รับNoClassDefFoundErrorเมื่อฉันรันแอปพลิเคชัน Java ของฉัน อะไรคือสาเหตุของสิ่งนี้


1
ฉันเชื่อว่ามันอาจเกิดขึ้นได้หากคุณไม่ได้รันโปรแกรมจาวาด้วยไวยากรณ์ที่ถูกต้อง ตัวอย่างเช่นคุณต้องเรียกคลาสของคุณจากโฟลเดอร์ root bin ด้วยชื่อแพคเกจแบบเต็ม (เช่น my.package.myClass) ฉันจะเฉพาะเจาะจงมากขึ้นถ้าฉันสามารถ แต่ฉันไม่มากจาวา ฉันจำได้ว่าทำอย่างนี้ไม่กี่ครั้ง
แฟรงค์เดอร์ตรงไปตรงมา

17
@BoltClock เราจำเป็นต้องมีคำถามที่เป็นที่ยอมรับในการระบุจำนวนที่ซ้ำกันไป ทำไมถึงเป็นแบบนี้ไม่ได้?
Raedwald

21
คุณได้พิจารณาเปลี่ยนคำตอบที่ยอมรับแล้วหรือไม่เพื่อให้ชุมชนที่พบว่ามีคุณค่ามากกว่านั้นอยู่ด้านบน
มาร์ตินสมิ ธ

คำตอบ:


264

สิ่งนี้เกิดขึ้นเมื่อมีไฟล์คลาสที่รหัสของคุณขึ้นอยู่กับมันและมีอยู่ในเวลารวบรวม แต่ไม่พบในขณะใช้งานจริง ค้นหาความแตกต่างในเวลาบิลด์และคลาสพา ธ ของรันไทม์ของคุณ


1
ฉันพบข้อผิดพลาดนี้เมื่อใส่ไฟล์ต้นฉบับภายใต้เนมสเปซ / แพ็กเกจที่ไม่ถูกต้อง ฉันคิดว่าฉันสามารถวางที่ใดก็ได้และคอมไพเลอร์ก็มีความสุข ปรากฎว่าฉันควรจะขยันมากขึ้นสำหรับ runtime จะมีความสุขเช่นกัน
CenterOrbit

1
ฉันมีข้อผิดพลาดนี้เมื่อเซิร์ฟเวอร์ของฉันมีหน่วยความจำไม่เพียงพอในระหว่างการอัปโหลดไฟล์ ทุกครั้งที่ฉันลองอัปโหลดฉันจะได้รับข้อผิดพลาดที่แตกต่างกัน ในที่สุดมันก็บอกว่าฉันมีพื้นที่กองไม่เพียงพอ
James M. Lay

81
คำตอบนี้ไม่จำเป็นต้องเป็นความจริงและจะทำให้คนอื่นเข้าใจผิด! ดูคำตอบที่ดีกว่าจาก Jared ด้านล่าง
Dave L.

4
@DaveL ขอบคุณ! คำตอบของ Jared ที่มีผู้โหวตมากกว่า 400 คนเป็นวิธีด้านล่าง! หนึ่งคำตอบด้วยคะแนน -4 ขึ้น (ลง?) เป็นวิธีที่อยู่เหนือมัน มีบางอย่างเกี่ยวกับตรรกะในการสั่งซื้อของตรรกะ
Saurabh Patil

1
นี่เป็นช็อตที่ยาวนานสำหรับบางคน แต่ฉันพบข้อผิดพลาดนี้เนื่องจากคลาสที่เป็นปัญหามี SimpleDateFormat ที่เริ่มต้นด้วยอักขระที่ไม่ถูกต้อง (ฉันมี T ตรงกลางแทน 'T')
Ryan D

817

ในขณะที่เป็นไปได้ว่านี่เป็นเพราะ classpath ไม่ตรงกันระหว่างเวลาคอมไพล์และรันไทม์ แต่ก็ไม่จำเป็นต้องเป็นเรื่องจริง

เป็นสิ่งสำคัญที่จะต้องรักษาข้อยกเว้นที่แตกต่างกันสองหรือสามข้อไว้ในหัวของเราในกรณีนี้:

  1. java.lang.ClassNotFoundException ข้อยกเว้นนี้บ่งชี้ว่าไม่พบคลาสบนคลาสพา ธ สิ่งนี้บ่งชี้ว่าเราพยายามโหลดนิยามคลาสและคลาสไม่มีอยู่ใน classpath

  2. java.lang.NoClassDefFoundError ข้อยกเว้นนี้บ่งชี้ว่า JVM ค้นหาในโครงสร้างข้อมูลนิยามคลาสภายในเพื่อหานิยามของคลาสและไม่พบ สิ่งนี้ต่างจากการบอกว่าไม่สามารถโหลดได้จากคลาสพา ธ โดยปกติแล้วสิ่งนี้บ่งชี้ว่าก่อนหน้านี้เราพยายามโหลดคลาสจาก classpath แต่มันล้มเหลวด้วยเหตุผลบางอย่าง - ตอนนี้เรากำลังพยายามใช้คลาสอีกครั้ง (และต้องโหลดอีกครั้งเนื่องจากมันล้มเหลวในครั้งที่แล้ว) แต่เรา ' ไม่แม้แต่จะพยายามโหลดเพราะเราล้มเหลวในการโหลดก่อนหน้า (และสงสัยว่าเราจะล้มเหลวอีกครั้ง) ความล้มเหลวก่อนหน้านี้อาจเป็น ClassNotFoundException หรือ ExceptionInInialializerError (ระบุความล้มเหลวในบล็อกการเริ่มต้นคงที่) หรือปัญหาอื่น ๆ ประเด็นคือ NoClassDefFoundError ไม่จำเป็นต้องเป็นปัญหา classpath


30
ขอบคุณที่พูดถึงสาเหตุของ NoClassDefFoundError สิ่งนี้ช่วยฉันได้มาก! ในกรณีของฉัน ExceptionInInialializerError ถูกส่งออกมาก่อนนั่นเป็นวิธีที่ฉันค้นพบเกี่ยวกับข้อผิดพลาดในบล็อกแบบสแตติก
โทมัส

@ Jared เมื่อฉันได้รับError: Could not find or load main classมันจะถูกจัดประเภทตามประเภทของข้อผิดพลาด?
Vikram

@Pops: ทำให้ภาษา verbose มากขึ้นเพื่อระบุวัตถุของคำกริยา "ลอง" :)
Jared

1
@Vikram "ไม่สามารถค้นหาหรือโหลดคลาสหลัก" ไม่ใช่ข้อยกเว้น Java ซึ่งเกิดจากตัวเรียกใช้งาน (ซึ่งตรวจสอบ JAR และแอตทริบิวต์รายการหลัก)
eckes

2
ClassNotFoundException ยังถูกส่งออกไปเมื่อคลาสมีการเตรียมใช้งานสแตติกที่ส่งข้อผิดพลาดหรือข้อยกเว้น พวกเขาน่าจะเลือกชื่ออื่นสำหรับเหตุการณ์นั้น
coladict

124

java.lang.NoClassDefFoundErrorนี่คือรหัสที่จะแสดงให้เห็นถึง โปรดดูคำตอบของ Jaredสำหรับคำอธิบายโดยละเอียด

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;
}

3
และเหตุผลก็คือหลังจากลองครั้งแรก jvm รู้แล้วว่ามันจะไม่ทำงานและโยนข้อยกเว้นที่แตกต่างกันครั้งที่สอง?
ikamen

@ikamen เห็นได้ชัดว่ามันได้เก็บบางส่วนของการเริ่มต้นเรียนที่ไม่ประสบความสำเร็จSimpleCalculatorหลังจากหารด้วยศูนย์? มีใครบางคนมีการอ้างอิงถึงเอกสารอย่างเป็นทางการสำหรับพฤติกรรมนี้หรือไม่?
ᴠɪɴᴄᴇɴᴛ

4
@PhilipRego ไม่แน่ใจว่าสิ่งที่คุณหมายถึงโดย 'บริสุทธิ์' NoClassDefFoundError ครั้งแรกที่new SimpleCalculator()มีการเรียกคุณจะได้รับ ExceptionInInialializerError โดยมีสาเหตุมาจาก ArithmeticException ครั้งที่สองที่คุณโทรหาnew SimpleCalculator()คุณจะได้รับ NoClassDefFoundError ล้วนๆ ประเด็นก็คือคุณจะได้รับ NoClassDefFoundError ด้วยเหตุผลอื่นนอกเหนือจาก SimpleCalculator.class ที่ไม่ได้อยู่ใน classpath ตอนรันไทม์
harperska

36

NoClassDefFoundError ใน Java

ความหมาย:

  1. Java Virtual Machine ไม่สามารถค้นหาคลาสเฉพาะที่รันไทม์ซึ่งมีอยู่ในเวลารวบรวม

  2. หากคลาสมีอยู่ในระหว่างการคอมไพล์ แต่ไม่สามารถใช้ได้ใน java classpath ระหว่างรันไทม์

ป้อนคำอธิบายรูปภาพที่นี่

ตัวอย่าง:

  1. คลาสไม่ได้อยู่ใน Classpath ไม่มีวิธีที่จะรู้ได้อย่างแน่นอน แต่คุณสามารถพิมพ์ System.getproperty ("java.classpath") ได้หลายครั้งและจะพิมพ์ classpath จากที่นั่นอย่างน้อยคุณจะได้ ความคิดของ classpath รันไทม์ที่แท้จริงของคุณ
  2. ตัวอย่างง่ายๆของ NoClassDefFoundError คือคลาสเป็นของไฟล์ JAR ที่หายไปหรือ JAR ไม่ได้ถูกเพิ่มเข้าไปใน classpath หรือบางครั้งชื่อของ jar ถูกเปลี่ยนโดยคนที่ชอบในกรณีของฉันหนึ่งในเพื่อนร่วมงานของฉันเปลี่ยน tibco.jar เป็น tibco_v3.jar ล้มเหลวด้วย java.lang.NoClassDefFoundError และฉันสงสัยว่ามีอะไรผิดปกติ

  3. เพียงแค่พยายามเรียกใช้ตัวเลือก -classpath อย่างชัดเจนกับ classpath ที่คุณคิดว่าจะใช้งานได้และหากใช้งานได้จะเป็นสัญญาณสั้น ๆ ว่ามีบางคนกำลังเอาชนะ java classpath

  4. ปัญหาสิทธิ์ในไฟล์ JAR ยังสามารถทำให้ NoClassDefFoundError ใน Java
  5. Typo บนการกำหนดค่า XML ยังสามารถทำให้ NoClassDefFoundError ใน Java
  6. เมื่อคลาสที่คอมไพล์ของคุณซึ่งกำหนดไว้ในแพ็คเกจไม่แสดงในแพ็คเกจเดียวกันในขณะที่โหลดเช่นในกรณีของ JApplet จะมีการโยน NoClassDefFoundError ใน Java

การแก้ปัญหาที่เป็นไปได้:

  1. คลาสไม่พร้อมใช้งานใน Java Classpath
  2. หากคุณกำลังทำงานในสภาพแวดล้อม J2EE มากกว่าการมองเห็นของ Class ท่ามกลาง Classloader หลายตัวยังสามารถทำให้ java.lang.NoClassDefFoundError ดูตัวอย่างและส่วนสถานการณ์สำหรับการสนทนาโดยละเอียด
  3. ตรวจสอบ java.lang.ExceptionInInialializerError ในไฟล์บันทึกของคุณ NoClassDefFoundError เนื่องจากความล้มเหลวของการเริ่มต้นคงที่ค่อนข้างบ่อย
  4. เนื่องจาก NoClassDefFoundError เป็น subclass ของ java.lang.LinkageError มันอาจเกิดขึ้นได้หากหนึ่งในนั้นพึ่งพาเช่นห้องสมุดพื้นเมืองอาจไม่สามารถใช้ได้
  5. สคริปต์เริ่มต้นใด ๆ ก็ตามจะแทนที่ตัวแปรสภาพแวดล้อม Classpath
  6. คุณอาจเรียกใช้โปรแกรมของคุณโดยใช้คำสั่ง jar และคลาสไม่ได้กำหนดไว้ในแอตทริบิวต์ ClassPath ของไฟล์ Manifest

แหล่งข้อมูล:

3 วิธีในการแก้ปัญหา NoClassDefFoundError

java.lang.NoClassDefFoundError รูปแบบปัญหา


1
คำตอบที่ดี ฉันคิดว่าฉันได้ลองทุกอย่างที่คุณแนะนำแล้วและยังมีปัญหานั้นอยู่ ฉันสามารถแยกบางส่วนของเหล่านี้เนื่องจากโถทำงานกับฤดูใบไม้ผลิ แต่ดูเหมือนจะไม่ชอบโดย java.sql (ในกรณีของฉันไดรเวอร์ sap db สำหรับ Hana)
JE Carter II

จริง ๆ แล้วมันเรียกว่า System.getproperty ("java.class.path")
RIJIK

33

ฉันพบว่าบางครั้งฉันได้รับข้อผิดพลาด NoClassDefFound เมื่อโค้ดถูกคอมไพล์ด้วยคลาสที่เข้ากันไม่ได้ของคลาสที่พบในรันไทม์ อินสแตนซ์เฉพาะที่ฉันจำได้คืออยู่ในไลบรารีแกน apache จริงๆแล้วมี 2 เวอร์ชันใน runtime classpath ของฉันและมันก็ล้าสมัยและเข้ากันไม่ได้และไม่ใช่รุ่นที่ถูกต้องทำให้เกิดข้อผิดพลาด NoClassDefFound นี่คือแอปบรรทัดคำสั่งที่ฉันใช้คำสั่งคล้ายกับสิ่งนี้

set classpath=%classpath%;axis.jar

ฉันสามารถรับเวอร์ชันที่เหมาะสมโดยใช้:

set classpath=axis.jar;%classpath%;

4
มีปัญหาเดียวกัน ปรากฎว่าฉันรวบรวมไฟล์ war ด้วย Java7 แต่การติดตั้ง Tomcat ของฉันใช้ Java6 ฉันต้องอัปเดตตัวแปรสภาพแวดล้อมของฉัน
duvo

4
หากสิ่งนี้เกิดขึ้นอย่างนั้นฉันจะบอกว่า Java ไม่เป็นระเบียบ +2 หากเป็นจริง ยังไม่สามารถยืนยันได้ หากพบว่าเป็นจริงจะทำ +1 อีก (ในความคิดเห็น)
ซูเปอร์โนวา

7

นี่เป็นทางออกที่ดีที่สุดที่ฉันพบ

สมมติว่าเรามีแพ็คเกจorg.mypackageที่มีคลาส:

  • HelloWorld (ชั้นหลัก)
  • SupportClass
  • UtilClass

และไฟล์ที่กำหนดแพ็คเกจนี้จะถูกจัดเก็บทางกายภาพภายใต้ไดเรกทอรีD:\myprogram(บน Windows) หรือ/home/user/myprogram(บน Linux)

โครงสร้างไฟล์จะมีลักษณะดังนี้: ป้อนคำอธิบายรูปภาพที่นี่

เมื่อเราเรียกใช้ Java org.mypackage.HelloWorldเราระบุชื่อของแอพลิเคชันในการทำงาน: อย่างไรก็ตามเราต้องบอก Java ว่าจะค้นหาไฟล์และไดเรคทอรีที่กำหนดแพ็คเกจของเราได้อย่างไร ดังนั้นเพื่อเปิดโปรแกรมเราต้องใช้คำสั่งต่อไปนี้: ป้อนคำอธิบายรูปภาพที่นี่


6

ฉันใช้Spring FrameworkกับMavenและแก้ไขข้อผิดพลาดนี้ในโครงการของฉัน

มีข้อผิดพลาดรันไทม์ในชั้นเรียน ฉันอ่านคุณสมบัติเป็นจำนวนเต็ม แต่เมื่ออ่านค่าจากไฟล์คุณสมบัติค่าของมันจะเป็นสองเท่า

ฤดูใบไม้ผลิไม่ได้ให้ฉันเต็มสแต็คร่องรอยของบนบรรทัดที่รันไทม์ล้มเหลว NoClassDefFoundErrorมันก็กล่าวว่า แต่เมื่อฉันเรียกใช้มันเป็นแอปพลิเคชัน Java ดั้งเดิม (นำออกจาก MVC) มันให้ExceptionInInitializerErrorซึ่งเป็นสาเหตุที่แท้จริงและสิ่งที่ฉันติดตามข้อผิดพลาด

คำตอบของ @xli ทำให้ฉันเข้าใจถึงสิ่งที่อาจผิดในรหัสของฉัน


1
สิ่งเดียวกันเกิดขึ้นกับฉันเมื่อเขียนโปรแกรม Servlet (ที่NoClassDefFoundErrorจริงแล้วเกิดจากExceptionInInitalizerErrorซึ่งเกิดจากDateTimeParseException) มันทำให้เข้าใจผิดเล็กน้อยใช่มั้ย ฉันรู้ว่าพวกเขาอาจมีเหตุผลของพวกเขาที่จะทำให้มันเป็นอย่างนั้น แต่มันก็ดีที่มีอย่างน้อยคำใบ้เล็ก ๆ น้อย ๆ นั่นNoClassDefFoundErrorเป็นผลมาจากข้อยกเว้นอื่นโดยไม่จำเป็นต้องอนุมานมัน การขว้างปาExceptionInInitializerErrorอีกครั้งจะมีความชัดเจนมากขึ้น บางครั้งการเชื่อมต่อระหว่างสองอาจไม่ชัดเจน
BartłomiejZieliński

5

ฉันได้รับ NoClassFoundError เมื่อโหลดคลาสโดย runtime class loader ไม่สามารถเข้าถึงคลาสที่โหลดโดย java rootloader แล้ว เนื่องจากตัวโหลดคลาสที่แตกต่างกันอยู่ในโดเมนความปลอดภัยที่แตกต่างกัน (ตามจาวา) jvm จะไม่อนุญาตให้คลาสที่โหลดโดย rootloader ได้รับการแก้ไขในพื้นที่ที่อยู่ของโหลดเดอร์รันไทม์

รันโปรแกรมด้วย 'java -javaagent: tracer.jar [YOUR 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;
            }
        });
    }
}

1
ลิงค์เสียชีวิต ลองรุ่นที่เก็บถาวร: web.archive.org/web/20131216000019/https://blogs.oracle.com/…
avgvstvs

5

กรณีที่น่าสนใจอย่างหนึ่งที่คุณอาจเห็นเป็นจำนวนมากNoClassDefFoundErrorsคือเมื่อคุณ:

  1. throwRuntimeExceptionในstaticบล็อกของชั้นเรียนของคุณExample
  2. ตัดมัน (หรือถ้ามันไม่สำคัญว่ามันจะถูกโยนในกรณีทดสอบ )
  3. ลองสร้างตัวอย่างของคลาสนี้ 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จะถูกโยนพร้อมกับจากบล็อกแบบคงที่ExceptionInInitializerErrorRuntimeException


ในกรณีนี้คือสิ่งสำคัญโดยเฉพาะอย่างยิ่งเมื่อคุณเห็นNoClassDefFoundErrorsของคุณในการทดสอบหน่วย

ในแบบที่คุณ "แบ่งปัน" การstaticดำเนินการบล็อกระหว่างการทดสอบ แต่เริ่มต้นExceptionInInitializerErrorจะเป็นเพียงในกรณีทดสอบหนึ่ง อันแรกที่ใช้Exampleคลาสที่มีปัญหา กรณีทดสอบอื่น ๆ ที่ใช้ในชั้นเรียนก็จะโยนExampleNoClassDefFoundErrors


4
นี่เป็นคำแนะนำที่มีประโยชน์ในชีวิตจริง ฉันเพิ่งมีสถานการณ์เดียวกันกับ initializers แอตทริบิวต์ class คุณมีโอกาสเพียงครั้งเดียวที่จะเห็นปัญหาที่แท้จริงในบันทึก เมื่อโหลดคลาสแล้ว (หรือพยายามแล้ว) คุณจะต้องรีสตาร์ททุกสิ่ง
DailyFrankPeter

4

เทคนิคด้านล่างช่วยฉันได้หลายครั้ง:

System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());

โดย TheNoDefFoundClass เป็นคลาสที่อาจ "หลงทาง" เนื่องจากการกำหนดค่าตามความชอบสำหรับไลบรารี่รุ่นเก่าที่ใช้โดยโปรแกรมของคุณ สิ่งนี้เกิดขึ้นได้บ่อยที่สุดเมื่อมีการปรับใช้ซอฟต์แวร์ไคลเอนต์ลงในคอนเทนเนอร์ที่โดดเด่นติดอาวุธด้วย classloaders ของตัวเองและ libs ยอดนิยมรุ่นโบราณจำนวนมาก


3

ในกรณีที่คุณสร้างรหัส (EMF ฯลฯ ) อาจมีตัวกำหนดค่าเริ่มต้นคงที่มากเกินไปซึ่งใช้พื้นที่สแต็กทั้งหมด

ดูคำถาม Stack Overflow วิธีเพิ่มขนาดสแต็ก Java? .


"EMF" ? คุณหมายถึง" MEF "หรือไม่
Peter Mortensen

2
Nope EMf เป็น Eclipse Modeling Framework ในยานยนต์เราอาจประสบกับข้อผิดพลาดนี้เมื่อเรียกใช้รหัสที่สร้างขึ้น
Aykut Kllic

1

ฉันแก้ไขปัญหาด้วยการปิดใช้งาน preDexL ไลบรารีสำหรับโมดูลทั้งหมด:

dexOptions {
        preDexLibraries false
        ...

1

NoClassDefFoundErrorยังสามารถเกิดขึ้นได้เมื่อstatic initializer พยายามโหลดบันเดิลรีซอร์สที่ไม่พร้อมใช้งานในรันไทม์ตัวอย่างเช่นไฟล์คุณสมบัติที่คลาสที่ได้รับผลกระทบพยายามโหลดจาก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);
}

สิ่งนี้ไม่ถูกต้อง ทรัพยากรที่หายไปจะไม่ให้ข้อผิดพลาดนี้กับคุณ คุณจะได้รับเมื่อคลาสขาดหายไป
สตีเฟ่นซี

@StephenC บางทีฉันควรเน้นการมีส่วนร่วมที่มากขึ้น for example a properties file that the affected class tries to load from the META-INF directoryแต่ที่ผมเขียน สิ่งนี้เกิดขึ้นกับฉันและฉันก็สามารถแก้ไขได้NoClassDefFoundErrorโดยการเพิ่มไฟล์คุณสมบัติที่หายไป ฉันเพิ่มคำตอบนี้อย่างแน่นอนเพราะไม่มีใครคาดหวังข้อผิดพลาดนี้ภายใต้สถานการณ์ที่กล่าวถึง
ᴠɪɴᴄᴇɴᴛ

1
คุณพลาดสิ่งที่สำคัญมากในคำอธิบายของคุณแล้วเนื่องจากวิธีเดียวที่ไฟล์ทรัพยากรที่ขาดหายไปอาจทำให้เกิดข้อยกเว้นนั้นคือถ้าคุณพยายามโหลดไฟล์ทรัพยากรในการstaticเริ่มต้น ... ซึ่งทำให้เกิดข้อยกเว้นที่ไม่ได้ตรวจสอบ ที่จะล้มเหลว. ข้อยกเว้นที่ไม่ได้ตรวจสอบใด ๆ ที่เผยแพร่จากการเริ่มต้นคงที่จะทำเช่นนั้น
สตีเฟ่นซี

หากฉันผิด (เช่นนี้ไม่ได้เกิดจากการstaticเริ่มต้นล้มเหลว) ฉันจะสนใจที่จะเห็นตัวอย่างจริง (เช่น MCVE) ที่แสดงให้เห็นถึงพฤติกรรม
สตีเฟ่นซี

1
@StephenC คุณพูดถูก: แม้ว่าฉันจะค้นหากรณีที่ฉันพบปัญหานี้และมันเกี่ยวข้องกับ initializer คงที่ที่พยายามโหลดกลุ่มทรัพยากรฉันจะเพิ่ม / แก้ไขคำอธิบายสาเหตุของฉันขอบคุณสำหรับการชี้สิ่งนี้ ออก.
ᴠɪɴᴄᴇɴᴛ

1

ฉันได้รับข้อผิดพลาดนี้เมื่อฉันเพิ่มการพึ่งพา Maven ของโมดูลอื่นในโครงการของฉันในที่สุดปัญหาก็ถูกแก้ไขโดยการเพิ่ม-Xss2mตัวเลือก JVM ของโปรแกรมของฉัน (เป็นค่าเริ่มต้นหนึ่งเมกะไบต์ตั้งแต่ JDK5.0) เชื่อว่าโปรแกรมมีสแต็กไม่เพียงพอในการโหลดคลาส


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 การโยกย้าย


0

สำเนาเช็คเอาต์สองฉบับที่แตกต่างกันของโครงการเดียวกัน

ในกรณีของฉันปัญหาคือ Eclipse ไม่สามารถแยกความแตกต่างระหว่างสองสำเนาที่แตกต่างกันของโครงการเดียวกัน ฉันมีหนึ่งถูกล็อกบน trunk (การควบคุมเวอร์ชัน SVN) และอีกอันหนึ่งทำงานในสาขาเดียวในแต่ละครั้ง ฉันลองทำการเปลี่ยนแปลงในสำเนาการทำงานเป็นกรณีทดสอบ JUnit ซึ่งรวมถึงการแยกคลาสส่วนตัวภายในให้เป็นคลาสสาธารณะด้วยตนเองและในขณะที่ทำงานอยู่ฉันเปิดสำเนาอีกชุดของโครงการเพื่อดูรอบ ๆ ส่วนหนึ่งของรหัสที่ต้องการการเปลี่ยนแปลง เมื่อถึงจุดหนึ่งก็NoClassDefFoundErrorโผล่ขึ้นมาบ่นว่าชั้นในส่วนตัวไม่อยู่ที่นั่น; การดับเบิลคลิกในการติดตามสแต็กนำฉันไปยังไฟล์ต้นฉบับในสำเนาโครงการที่ไม่ถูกต้อง

การปิดสำเนาของโปรเจ็กต์และเรียกใช้กรณีทดสอบอีกครั้งทำให้ปัญหาหมดไป


0

ข้อผิดพลาดนี้อาจเกิดจากข้อกำหนดรุ่น Java ที่ไม่ได้ตรวจสอบ

ในกรณีของฉันฉันสามารถแก้ไขข้อผิดพลาดนี้ในขณะที่สร้างโครงการโอเพนซอร์สสูงโปรไฟล์โดยเปลี่ยนจาก Java 9 เป็น Java 8 โดยใช้SDKMAN! .

sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu

จากนั้นทำการติดตั้งใหม่ทั้งหมดตามที่อธิบายไว้ด้านล่าง


เมื่อใช้Mavenเป็นสร้างเครื่องมือของคุณจะเป็นประโยชน์บางครั้ง - และมักจะพอใจที่จะทำสะอาด 'ติดตั้ง' สร้างกับการทดสอบพิการ

mvn clean install -DskipTests

เมื่อทุกอย่างถูกสร้างและติดตั้งแล้วคุณสามารถดำเนินการทดสอบได้

mvn test

0

ฉันได้รับข้อผิดพลาด NoClassDefFound เมื่อฉันไม่ได้ส่งออกคลาสบนแท็บ "สั่งซื้อและส่งออก" ใน Java Build Path ของโครงการของฉัน ตรวจสอบให้แน่ใจว่าได้ใส่เครื่องหมายถูกในแท็บ "สั่งซื้อและส่งออก" ของการอ้างอิงใด ๆ ที่คุณเพิ่มไปยังเส้นทางการสร้างของโครงการ ดูคำเตือน Eclipse: XXXXXXXXXXX.jar จะไม่ถูกส่งออกหรือเผยแพร่ Runtime ClassNotFoundExceptions อาจส่งผลให้


0

อาจเป็นเพราะคุณคัดลอกไฟล์รหัสจาก IDE ด้วยชื่อแพ็กเกจที่แน่นอนและคุณต้องการลองรันโดยใช้เทอร์มินัล คุณจะต้องลบชื่อแพ็คเกจออกจากรหัสก่อน สิ่งนี้เกิดขึ้นกับฉัน


0

ในกรณีของฉันฉันได้รับข้อผิดพลาดนี้เนื่องจากไม่ตรงกันในรุ่น JDK เมื่อฉันพยายามเรียกใช้แอพพลิเคชั่นจาก Intelij มันไม่ทำงาน แต่ก็เปิดใช้งานจากบรรทัดคำสั่งได้ผล นี่เป็นเพราะ Intelij พยายามที่จะรันด้วย Java 11 JDK ที่ติดตั้ง แต่ในบรรทัดคำสั่งมันกำลังทำงานกับ Java 8 JDK หลังจากสลับการตั้งค่านั้นในไฟล์> โครงสร้างโครงการ> การตั้งค่าโครงการ> SDK โครงการมันใช้งานได้สำหรับฉัน


0

ทุกคนพูดถึงที่นี่เกี่ยวกับบางสิ่งที่เกี่ยวกับการกำหนดค่า Java ปัญหา JVM ฯลฯ ในกรณีของฉันข้อผิดพลาดไม่เกี่ยวข้องกับหัวข้อเหล่านี้เลยและมีเหตุผลเล็กน้อยและง่ายต่อการแก้ปัญหา: ฉันมีคำอธิบายประกอบผิดที่จุดปลายทางของฉันในคอนโทรลเลอร์ แอปพลิเคชั่น Spring Boot)


0

ฉันมีปัญหาที่น่าสนใจกับ NoClassDefFoundError ใน JavaEE ที่ทำงานกับเซิร์ฟเวอร์ Liberty ฉันใช้อะแดปเตอร์ทรัพยากร IMS และ server.xml ของฉันมีอะแดปเตอร์ทรัพยากรสำหรับ imsudbJXA.rar แล้ว เมื่อฉันเพิ่มอะแดปเตอร์ใหม่สำหรับ imsudbXA.rar ฉันจะเริ่มรับข้อผิดพลาดนี้สำหรับวัตถุอินสแตนซ์สำหรับ DLIException, IMSConnectionSpec หรือ SQLInteractionSpec ฉันไม่สามารถหาสาเหตุได้ แต่ฉันแก้ไขด้วยการสร้าง server.xml ใหม่สำหรับงานของฉันโดยใช้เพียง imsudbXA.rar ฉันแน่ใจว่าใช้อะแดปเตอร์ทรัพยากรหลายตัวใน server.xml ไม่เป็นไรฉันไม่มีเวลาดู


-1

Java ไม่พบคลาส A ในรันไทม์ Class A อยู่ในโครงการ Maven ArtClient จากพื้นที่ทำงานอื่น ดังนั้นฉันจึงนำเข้า ArtClient ไปยังโครงการ Eclipse ของฉัน สองโครงการของฉันใช้ ArtClient เป็นการพึ่งพา ฉันเปลี่ยนการอ้างอิงไลบรารีเป็นการอ้างอิงโครงการสำหรับสิ่งเหล่านี้ (Build Path -> Configure Build Path)

และปัญหาก็หมดไป


-1

ฉันมีปัญหาเดียวกันและฉันเป็นสต็อกเป็นเวลาหลายชั่วโมง

ฉันพบวิธีแก้ปัญหา ในกรณีของฉันมีวิธีการคงที่ที่กำหนดเนื่องจากการที่ JVM ไม่สามารถสร้างวัตถุอื่นของคลาสนั้น

ตัวอย่างเช่น,

private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");

-6

ฉันได้รับข้อความนี้หลังจากลบไฟล์สองไฟล์ออกจากไลบรารี SRC และเมื่อฉันนำไฟล์เหล่านั้นกลับมาฉันก็ยังเห็นข้อความแสดงข้อผิดพลาดนี้อยู่

วิธีแก้ปัญหาของฉันคือ: รีสตาร์ท Eclipse ตั้งแต่นั้นมาฉันไม่เห็นข้อความนี้อีก :-)


4
นั่นคือคำตอบที่ได้รับการโหวตมากที่สุดเมื่อคุณคอมไพล์ครั้งแรกไฟล์อยู่ที่นั่นแล้วคุณก็ลบบางไฟล์คลาสที่ถูกลบดังนั้นตอนรันไทม์คุณได้ ClassNotFound แล้วคุณก็จะย้อนกลับ แต่ Eclipse ยังไม่ สังเกตเห็นว่าคลาสที่สร้างขึ้นยังคงหายไป แต่หลังจากคุณรีสตาร์ท Eclipse แล้วเวิร์กสเปซก็ถูกรีเฟรชและคลาสก็พร้อมใช้งานอีกครั้ง แต่โดยทั่วไปนี่ไม่ใช่วิธีแก้ปัญหาหรือวิธีแก้ปัญหาวิธีแก้ปัญหาคือการค้นหาว่า classpath
Jose Manuel Gomez Alvarez

-7

ตรวจสอบให้แน่ใจว่าการจับคู่นี้ในmodule:appและmodule:lib:

android {
    compileSdkVersion 23
    buildToolsVersion '22.0.1'
    packagingOptions {
    }

    defaultConfig {
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 11
        versionName "2.1"
    }

3
โซลูชันของคุณมีความเกี่ยวข้องกับปัญหาที่พบบ่อยเพียงใด
Taavi Ilves

การกำหนดค่าตัวอย่างไม่สมดุล (สาม{sและสอง}) คุณซ่อมได้หรือไม่?
Peter Mortensen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.