[java] Java에서 NoClassDefFoundError가 발생하는 이유는 무엇입니까?

NoClassDefFoundErrorJava 애플리케이션을 실행할 때을 받고 있습니다. 일반적으로 이것의 원인은 무엇입니까?



답변

이것은 코드가 의존하는 클래스 파일이 있고 컴파일 타임에 존재하지만 런타임에는 찾을 수 없을 때 발생합니다. 빌드 시간과 런타임 클래스 경로의 차이점을 찾으십시오.


답변

컴파일 타임과 런타임 사이의 클래스 경로 불일치 때문일 수도 있지만 반드시 그런 것은 아닙니다.

이 경우 두세 가지 예외를 머리에 똑바로 유지하는 것이 중요합니다.

  1. java.lang.ClassNotFoundException 이 예외는 클래스가 클래스 경로에서 발견되지 않았 음을 나타냅니다. 이것은 클래스 정의를로드하려고했지만 클래스가 클래스 경로에 존재하지 않았 음을 나타냅니다.

  2. java.lang.NoClassDefFoundError 이 예외는 JVM이 클래스 정의에 대한 내부 클래스 정의 데이터 구조를 찾아서 찾지 못했음을 나타냅니다. 이것은 클래스 경로에서로드 할 수 없다는 것과 다릅니다. 일반적으로 이것은 이전에 클래스 경로에서 클래스를로드하려고 시도했지만 어떤 이유로 실패했습니다. 이제 클래스를 다시 사용하려고합니다 (따라서 마지막으로 실패했기 때문에로드해야합니다). 이전에로드하지 못했기 때문에 다시로드하려고 시도하지 않습니다 (그리고 다시 실패 할 것으로 의심 됨). 이전 실패는 ClassNotFoundException 또는 ExceptionInInitializerError (정적 초기화 블록의 실패를 표시 함) 또는 기타 여러 가지 문제점 일 수 있습니다. 요점은 NoClassDefFoundError가 반드시 클래스 경로 문제 일 필요는 없다는 것입니다.


답변

다음은 설명하는 코드입니다 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;
}


답변

Java에서 NoClassDefFoundError

정의:

  1. Java Virtual Machine은 컴파일 타임에 사용 가능한 런타임에 특정 클래스를 찾을 수 없습니다.

  2. 컴파일 타임 동안 클래스가 있었지만 런타임 동안 Java 클래스 경로에서 사용할 수없는 경우

여기에 이미지 설명을 입력하십시오

예 :

  1. 클래스가 Classpath에 있지 않다는 것을 알 수있는 확실한 방법은 없지만 System.getproperty ( “java.classpath”)를 인쇄하여 적어도 클래스 클래스를 인쇄 할 수 있습니다. 실제 런타임 클래스 경로에 대한 아이디어.
  2. NoClassDefFoundError의 간단한 예는 클래스가 누락 된 JAR 파일에 속하거나 JAR이 클래스 경로에 추가되지 않았거나 때로는 내 동료 중 하나가 tibco.jar을 tibco_v3.jar로 변경하고 프로그램이 다음과 같은 누군가에 의해 jar의 이름이 변경된 경우입니다. java.lang.NoClassDefFoundError로 실패하고 무엇이 잘못되었는지 궁금합니다.

  3. 작동 할 것이라고 생각하는 클래스 경로와 함께 명시 적으로 -classpath 옵션으로 실행하려고 시도하고 작동하면 누군가가 Java 클래스 경로를 재정의한다는 짧은 신호입니다.

  4. JAR 파일에 대한 권한 문제로 인해 Java에서 NoClassDefFoundError가 발생할 수도 있습니다.
  5. XML 구성의 오타도 Java에서 NoClassDefFoundError를 일으킬 수 있습니다.
  6. 패키지에 정의 된 컴파일 된 클래스가 JApplet의 경우와 같이로드하는 동안 동일한 패키지에 없으면 Java에서 NoClassDefFoundError가 발생합니다.

가능한 해결책:

  1. 이 클래스는 Java 클래스 경로에서 사용할 수 없습니다.
  2. J2EE 환경에서 여러 클래스 로더 중 클래스의 가시성보다 java.lang.NoClassDefFoundError가 발생할 수있는 경우보다 자세한 내용은 예제 및 시나리오 섹션을 참조하십시오.
  3. 로그 파일에서 java.lang.ExceptionInInitializerError를 확인하십시오. 정적 초기화 실패로 인한 NoClassDefFoundError는 매우 일반적입니다.
  4. NoClassDefFoundError는 java.lang.LinkageError의 서브 클래스이므로 네이티브 라이브러리와 같은 종속성 중 하나를 사용할 수없는 경우에도 발생할 수 있습니다.
  5. 모든 시작 스크립트가 Classpath 환경 변수를 대체합니다.
  6. jar 명령을 사용하여 프로그램을 실행 중일 수 있으며 매니페스트 파일의 ClassPath 속성에 클래스가 정의되어 있지 않습니다.

자원:

NoClassDefFoundError를 해결하는 3 가지 방법

java.lang.NoClassDefFoundError 문제 패턴


답변

런타임에 발견 된 호환되지 않는 클래스의 클래스로 코드를 컴파일 할 때 때때로 NoClassDefFound 오류가 발생한다는 것을 알았습니다. 내가 기억하는 특정 인스턴스는 아파치 축 라이브러리입니다. 실제로 런타임 클래스 경로에 2 가지 버전이 있었고 오래된 버전과 호환되지 않는 버전을 선택했지만 올바른 버전이 아니므로 NoClassDefFound 오류가 발생했습니다. 이것은 비슷한 명령을 사용하는 명령 줄 앱에있었습니다.

set classpath=%classpath%;axis.jar

다음을 사용하여 올바른 버전을 선택할 수있었습니다.

set classpath=axis.jar;%classpath%;


답변

이것이 지금까지 찾은 최고의 솔루션 입니다.

org.mypackage클래스를 포함 하는 패키지가 있다고 가정 해보십시오 .

  • HelloWorld (메인 클래스)
  • 지원 클래스
  • UtilClass

이 패키지를 정의하는 파일은 디렉토리 D:\myprogram(Windows) 또는 /home/user/myprogram(Linux) 에 실제로 저장됩니다 .

파일 구조는 다음과 같습니다.
여기에 이미지 설명을 입력하십시오

Java를 호출 할 때 실행할 애플리케이션 이름을 지정합니다 org.mypackage.HelloWorld.. 그러나 패키지를 정의하는 파일과 디렉토리를 찾을 위치를 Java에 알려야합니다. 따라서 프로그램을 시작하려면 다음 명령을 사용해야합니다.
여기에 이미지 설명을 입력하십시오


답변

Maven 과 함께 Spring Framework 를 사용 하고 있었고 프로젝트 에서이 오류를 해결했습니다.

클래스에 런타임 오류가있었습니다. 속성을 정수로 읽는 중이지만 속성 파일에서 값을 읽을 때 값이 두 배였습니다.

Spring은 런타임이 실패한 라인에 대한 전체 스택 추적을 제공하지 않았습니다. 단순히 말했다 NoClassDefFoundError. 그러나 MVC에서 가져 오는 네이티브 Java 응용 프로그램으로 실행했을 때 ExceptionInInitializerError원인이 무엇인지, 어떻게 오류를 추적했는지 알 수 있습니다.

@xli의 대답은 내 코드에서 무엇이 잘못되었는지에 대한 통찰력을 제공했습니다.