NoClassDefFoundError와 ClassNotFoundException의 차이점은 무엇입니까?


371

차이점은 무엇이며 NoClassDefFoundError그리고 ClassNotFoundException?

무엇이 던져지게 하는가? 그들은 어떻게 해결할 수 있습니까?

새로운 jar 파일을 포함하도록 기존 코드를 수정할 때 종종 이러한 Throwable이 발생합니다. 웹 시작을 통해 배포 된 Java 응용 프로그램의 클라이언트 측과 서버 측 모두에서 적중했습니다.

내가 만난 이유 :

  1. build.xml코드의 클라이언트 측에 포함되지 않은 패키지
  2. 우리가 사용하는 새로운 jar에 대한 런타임 클래스 경로가 없습니다.
  3. 이전 jar과 버전 충돌

내가 오늘 이것들을 만날 때 나는 일을 잘하기 위해 흔적과 실수를한다. 더 명확하고 이해가 필요합니다.


나는 종종 -verbose(예를 들어 -verbose:class -verbose:jni) 도움으로 JVM을 실행하는 것을 발견 하지만 유용한 정보를 제공하지 않는다는 mogsie의 답변 아래 :(
PJTraill

답변:


388

Java API 사양과의 차이점은 다음과 같습니다.

의 경우 ClassNotFoundException:

애플리케이션이 다음을 사용하여 문자열 이름을 통해 클래스에로드하려고 할 때 발생합니다.

  • forName클래스 의 메소드 Class.
  • findSystemClass클래스 의 메소드 ClassLoader.
  • loadClass클래스 의 메소드 ClassLoader.

지정된 이름의 클래스에 대한 정의를 찾을 수 없습니다.

의 경우 NoClassDefFoundError:

Java Virtual Machine 또는 ClassLoader인스턴스가 클래스의 정의 (일반 메소드 호출의 일부 또는 새 표현식을 사용하여 새 인스턴스를 작성하는 일부)를로드하려고 시도하고 클래스 정의를 찾을 수없는 경우 발생합니다.

검색된 클래스 정의는 현재 실행중인 클래스가 컴파일 될 때 존재하지만 정의를 더 이상 찾을 수 없습니다.

따라서 NoClassDefFoundError소스가 성공적으로 컴파일 될 때 발생하지만 런타임에 필요한 class파일을 찾을 수없는 것으로 보입니다 . 이것은 필요한 class파일이 모두 포함되어 있지 않은 JAR 파일의 배포 또는 프로덕션에서 발생할 수있는 것일 수 있습니다 .

에 관해서 ClassNotFoundException는 런타임에 클래스에 대한 반사 호출을 시도한 것일 수 있지만 프로그램이 호출하려는 클래스가 존재하지 않습니다.

둘 사이의 차이점은 하나는 Error이고 다른 하나는이라는 것입니다 Exception. with NoClassDefFoundErrorError및 Java Virtual Machine에서 찾은 클래스를 찾는 데 문제가 있습니다. 컴파일 타임에 작동 할 것으로 예상 된 프로그램은 class파일을 찾을 수 없어서 실행할 수 없거나 컴파일 타임 에 생성되거나 발생 된 것과 동일하지 않습니다. JVM이 프로그램을 시작할 수 없기 때문에 이것은 매우 중요한 오류입니다.

반면에는 ClassNotFoundExceptionException이므로 어느 정도 예상되며 복구 할 수있는 것입니다. 리플렉션을 사용하면 오류가 발생하기 쉬울 수 있습니다 (일부 예상대로 진행되지 않을 것으로 예상됩니다. 필요한 모든 클래스가 존재하는지 확인하는 컴파일 타임 검사가 없으므로 원하는 클래스를 찾는 데 문제가 런타임에 나타납니다. .


53
NoClassDefFoundError일반적으로 클래스의 정적 블록 또는 정적 필드 초기화에 문제가 발생하면 예외가 발생하므로 클래스를 성공적으로 초기화 할 수 없습니다.
Dagang

7
공감. 하나는 Error이고 다른 하나는 Exception입니다. :)
Ravi

83

보고 된 클래스를 ClassLoader에서 찾을 수없는 경우 ClassNotFoundException이 발생합니다. 이것은 일반적으로 클래스가 CLASSPATH에서 누락되었음을 의미합니다. 또한 문제의 클래스가 상위 클래스 로더에로드 된 다른 클래스에서로드하려고하므로 하위 클래스 로더의 클래스가 표시되지 않을 수도 있습니다. App Server와 같이보다 복잡한 환경에서 작업하는 경우가 종종 있습니다 (WebSphere는 이러한 클래스 로더 문제로 유명합니다).

사람들은 종종 혼동하는 경향 java.lang.NoClassDefFoundErrorjava.lang.ClassNotFoundException중요한 차이있다 그러나. 예를 들어 예외 (실제로 오류 java.lang.NoClassDefFoundError는 java.lang.Error의 서브 클래스입니다)

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

ActiveMQConnectionFactory 클래스가 CLASSPATH에 없다는 것을 의미하지는 않습니다. 사실 그 반대입니다. 이는 클래스 로더가 ActiveMQConnectionFactory 클래스를 찾았지만 클래스를로드하려고 할 때 클래스 정의를 읽는 중에 오류가 발생했음을 의미합니다. 일반적으로 문제의 클래스에 클래스 로더에서 찾을 수없는 클래스를 사용하는 정적 블록 또는 멤버가있는 경우 발생합니다. 따라서 범인을 찾으려면 해당 클래스의 소스 (이 경우 ActiveMQConnectionFactory)를보고 정적 블록 또는 정적 멤버를 사용하는 코드를 찾으십시오. 소스에 액세스 할 수 없으면 JAD를 사용하여 간단히 디 컴파일하십시오.

코드를 검사 할 때 아래와 같은 코드 행을 찾으면 CLASSPATH에 SomeClass 클래스가 있는지 확인하십시오.

private static SomeClass foo = new SomeClass();

팁 : 클래스가 속한 jar을 찾으려면 웹 사이트 jarFinder를 사용할 수 있습니다. 이를 통해 와일드 카드를 사용하여 클래스 이름을 지정하고 jar 데이터베이스에서 클래스를 검색 할 수 있습니다. jarhoo를 사용하면 동일한 작업을 수행 할 수 있지만 더 이상 사용할 수 없습니다.

클래스가 속한 jar을 로컬 경로에서 찾으려면 jarscan ( http://www.inetfeedback.com/jarscan/ ) 과 같은 유틸리티를 사용할 수 있습니다 . 단지 찾으려는 클래스와 jar 및 zip 파일에서 클래스 검색을 시작하려는 루트 디렉토리 경로 만 지정하면됩니다.


9
이것이 마지막으로 투표 한 정확한 답변이라는 것이 재미 있습니다. (투표하기 전에도 -1). ClassNotFoundException은 CL에 .class 파일이 표시되지 않음을 의미합니다. NoClassDefFoundError는 .class 파일이로드 할 수 없음 (JNI 오류 일 수 있음)을 의미합니다.
user43685

1
이 답변이 답변 양식 coobird와 모순되지 않습니까?
zardosht

정적 블록의 비슷한 예를 시도했습니다. 내 클래스 Class1에는 정적 변수 "private static B foo = new B ();"가 있습니다. 컴파일 후 bin 폴더에서 B.class 파일을 제거했습니다. 이제 Class1의 객체를 만들 때 세 번째 클래스의 Main 메소드에서. rror는 다음과 같이 간주됩니다 : -------- "스레드"main "의 예외 java.lang.NoClassDefFoundError : spring / B"........ 그래서 그것이 발견되지 않은 클래스를 정확하게 언급합니다 즉, 외부 클래스가 아닌 정적 블록에서 참조되는 클래스 이므로이 답변과 반대됩니다.
카우 k 레

"ActiveMQConnectionFactory 클래스가 CLASSPATH에 없음을 의미하지는 않습니다"와 관련하여 +1
akila

35

NoClassDefFoundError기본적으로 연결 오류입니다. (정적으로 "new"로) 객체를 인스턴스화하려고 시도 할 때 발생하며 컴파일 중에는 찾을 수 없습니다.

ClassNotFoundException더 일반적이며 존재하지 않는 클래스를 사용하려고 할 때 런타임 예외입니다. 예를 들어 함수에 매개 변수가 인터페이스를 허용하고 누군가 해당 인터페이스를 구현하는 클래스를 전달하지만 해당 클래스에 액세스 할 수는 없습니다. loadClass()또는 사용과 같은 동적 클래스 로딩의 경우도 다룹니다 Class.forName().


29

NCDFE (NoClassDefFoundError)는 코드에서 "new Y ()"를 실행하고 Y 클래스를 찾을 수 없을 때 발생합니다.

다른 의견에서 알 수 있듯이 Y가 클래스 로더에서 누락되었을 수 있지만 Y 클래스가 서명되지 않았거나 서명이 잘못되었거나 코드에 표시되지 않는 다른 클래스 로더에 의해 Y가로드되었을 수 있습니다. 또는 Y가 Z에 의존하여 위의 이유로로드 할 수 없습니다.

이 경우 JVM은 X (NCDFE)로드 결과를 기억하며 Y를 요청할 때마다 이유를 알리지 않고 새 NCDFE를 던집니다.

클래스 {
  정적 클래스 b {}
  공개 정적 무효 메인 (문자열 인수 []) {
    System.out.println ( "첫 번째 시도 새 b () :");
    {new b ();를 시도하십시오 } catch (Throwable t) {t.printStackTrace ();}
    System.out.println ( "\ n 둘째 새 b () :") 시도;
    {new b ();를 시도하십시오 } catch (Throwable t) {t.printStackTrace ();}
  }
}

이것을 어딘가에 a.java로 저장하십시오.

이 코드는 단순히 새로운 "b"클래스를 두 번 인스턴스화하려고 시도합니다. 그 외에는 버그가 없으며 아무 것도하지 않습니다.

로 코드를 컴파일 한 javac a.java다음 호출하여 a를 실행하십시오. java -cp . a두 줄의 텍스트를 인쇄하면 오류없이 정상적으로 실행됩니다.

그런 다음 "a $ b.class"파일을 삭제하거나 가비지로 채우거나 a.class를 복사하여 누락되거나 손상된 클래스를 시뮬레이션하십시오. 다음과 같은 일이 발생합니다.

먼저 새로운 b ()를 시도하십시오.
java.lang.NoClassDefFoundError : a $ b
    a.main (a.java:5)에서
원인 : 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.Launcher $ AppClassLoader.loadClass (Launcher.java:301)에서
    java.lang.ClassLoader.loadClass (ClassLoader.java:252)에서
    java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320)에서
    ... 1 더

두 번째 시도 새로운 b () :
java.lang.NoClassDefFoundError : a $ b
    a.main (a.java:7)에서

첫 번째 호출은 ClassNotFoundException (클래스를 찾을 수 없을 때 클래스 로더에 의해 발생)을 초래하며, 문제의 코드 ( new b())가 작동 하기 때문에 검사되지 않은 NoClassDefFoundError로 랩핑 되어야합니다.

두 번째 시도는 물론 실패하지만, 클래스 로더가 실패한 클래스 로더를 기억하는 것처럼 보이기 때문에 랩 된 예외는 더 이상 볼 수 없습니다. 당신은 실제로 일어난 일에 대한 단서가없는 NCDFE 만 봅니다.

따라서 근본 원인이없는 NCDFE가 표시되는 경우 오류가 발생한 원인을 찾기 위해 클래스가 처음로드 된 시점까지 추적 할 수 있는지 확인해야합니다.


-verbose특정 JVM에 따라를 사용하여 JVM을 실행 하거나 비슷한 옵션을 사용하는 것은 어떻습니까? 아마 -verbose:class, 어쩌면 -verbose:class:jni경우 JNI를 사용하지만, 나는 확실히 구문에 대한 아니에요. 이것이 유용한 경우 결과를 표시 할 수 있습니다.
PJTraill

누락 된 클래스와 관련된 추가 출력을 제공 -verbose:class하거나 -verbose:jni제공하지 마십시오 .
mogsie

1
결과가 실망 스럽더라도 시도해 주셔서 감사합니다. (그 이후로 PS는 그것이 -verbose:class:jni틀렸다는 것을 알았습니다 . 하나는 두 가지 옵션을 지정해야 -verbose:class -verbose:jni합니다.)
PJTraill

2
마지막 문장 * 1,000,000 : 근본 원인이없는 NCDFE가 표시되는 경우 오류가 발생한 원인을 찾기 위해 클래스가 처음로드 된 시점으로 되돌릴 수 있는지 확인해야합니다.
batwad

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 파일을 삭제하고 Test 클래스를 실행하면 던져집니다.

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: JVM (Java Virtual Machine)이 클래스 정의를로드하려고 시도하고 클래스 정의를 찾을 수없는 경우 발생합니다.


-verbose특정 JVM에 따라를 사용하여 JVM을 실행 하거나 비슷한 옵션을 사용하는 것은 어떻습니까? 아마 -verbose:class, 어쩌면 -verbose:class:jni경우 JNI를 사용하지만, 나는 확실히 구문에 대한 아니에요.
PJTraill 2016 년

-verbose:class:jni잘못되었지만 두 가지 옵션을 전달할 수 있습니다 -verbose:class -verbose:jni..
PJTraill

15

그들 각각을 얻는 이유와 그러한 오류를 다루는 방법에 대한 생각 과정은 무엇입니까?

그들은 밀접한 관련이 있습니다. ClassNotFoundExceptionJava가 이름으로 특정 클래스를 찾다가 성공적으로로드하지 못한 경우 A 가 발생합니다. A는 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/Class2B를 컴파일하는 동안 존재하지만, 실행하는 동안 발견되지, 다음이 발생합니다 NoClassDefFoundError.

둘 다 런타임 예외입니다.


9

ClassNotFoundException 은 String을 통해 클래스를 참조하여 클래스를로드하려고 할 때 발생합니다. 예를 들어 Class.forName ()의 매개 변수는 문자열이며 이는 유효하지 않은 이진 이름이 클래스 로더에 전달 될 가능성을 높입니다.

잠재적으로 유효하지 않은 2 진 이름이 발견되면 ClassNotFoundException이 발생합니다. 예를 들어, 클래스 이름에 '/'문자가 있으면 ClassNotFoundException이 발생합니다. 클래스 경로에서 직접 참조 된 클래스를 사용할 수없는 경우에도 발생합니다.

반면에 NoClassDefFoundError 가 발생합니다.

  • 클래스의 실제 물리적 표현-.class 파일을 사용할 수없는 경우
  • 또는 클래스가 이미 다른 클래스 로더에로드되었습니다 (보통 부모 클래스 로더가 클래스를로드 했으므로 클래스를 다시로드 할 수 없음).
  • 또는 호환되지 않는 클래스 정의가 발견되면 클래스 파일의 이름이 요청 된 이름과 일치하지 않습니다.
  • 또는 (가장 중요한) 종속 클래스를 찾을 수없는 경우. 이 경우 직접 참조 된 클래스를 찾아로드했지만 종속 클래스를 사용할 수 없거나로드 할 수 없습니다. 직접 참조 된 클래스를 Class.forName 또는 이와 동등한 메소드를 통해로드 할 수있는 시나리오입니다. 연결에 실패했음을 나타냅니다.

간단히 말해서, 클래스 로더가 클래스 정의를 찾을 수 없거나로드 할 수없는 경우 (ClassNotFoundException에 대한 문자열 기반 클래스 로딩과는 반대로) 이전에 없었던 클래스를로드하는 new () 문 또는 메소드 호출에서 일반적으로 NoClassDefFoundError가 발생합니다 ( 에스).

결국 클래스를로드 할 수 없을 때 ClassNotFoundException 인스턴스를 발생시키는 것은 ClassLoader 구현에 달려 있습니다. 대부분의 사용자 정의 클래스 로더 구현은 URLClassLoader를 확장하기 때문에이를 수행합니다. 일반적으로 클래스 로더는 메소드 구현에서 명시 적으로 NoClassDefFoundError를 발생시키지 않습니다.이 예외는 일반적으로 클래스 로더 자체가 아니라 HotSpot 컴파일러의 JVM에서 발생합니다.


'클래스 파일의 이름이 요청한 이름과 일치하지 않습니다.' 이것은 매우 일반적인 원인입니다.
Lorne의 후작

8

ClassNotFoundException과 NoClassDefFoundError의 차이점

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


맑은 것은 아닙니다. "클래스 경로에서 업데이트되지 않음"은 모호하고 정확하지 않습니다. 이 중 하나에 대해 JAR되지되고 있는 클래스 패스에, 또는 잘못된 버전의 클래스 패스에되는 JAR의. 그리고 철자 오류. 그리고 정보가 펑키 그래픽으로 게시되었으므로이 문제를 해결할 수 없습니다.
Stephen C

8

이름 자체를 통해 우리는 하나의 이름 Exception과 다른 이름을 쉽게 식별 할 수 있습니다 Error.

예외 : 프로그램 실행 중에 예외가 발생합니다. 프로그래머는 try catch 블록으로 이러한 예외를 처리 할 수 ​​있습니다. 두 가지 유형의 예외가 있습니다. 컴파일 타임에 throw되는 확인 된 예외입니다. 런타임에 발생하는 런타임 예외. 이러한 예외는 일반적으로 잘못된 프로그래밍으로 인해 발생합니다.

오류 : 이들은 예외가 아니며 프로그래머의 범위를 벗어납니다. 이러한 오류는 일반적으로 JVM에서 발생합니다.


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

차:

ClassNotFoundException :

  • 클래스 로더 는 우리가 얻는 클래스 로딩 서브 시스템링크 단계 에서 언급 한 클래스 바이트 코드 를 확인 하지 못한다 .ClassNotFoundException
  • ClassNotFoundExceptionjava.lang.Exception클래스 에서 직접 파생 된 확인 된 예외 이므로 명시 적으로 처리해야합니다.
  • ClassNotFoundExceptionClassLoader.loadClass (), Class.forName () 및 ClassLoader.findSystemClass ()를 사용하여 런타임에 클래스 이름을 제공하여 클래스 의 명시 적로드 가 포함 되면 나타납니다 .

NoClassDefFoundError :

  • 클래스 로더 는 우리가 얻는 클래스 로딩 서브 시스템링크 단계 에서 클래스의 참조 를 해석 하지 못합니다 .NoClassDefFoundError
  • NoClassDefFoundErrorLinkageError클래스에서 파생 된 오류로, 클래스가 다른 클래스에 종속되어 있고 컴파일 후 해당 클래스가 호환되지 않는 오류 사례를 나타내는 데 사용됩니다.
  • NoClassDefFoundError해당 클래스의 메소드 호출 또는 변수 액세스로 인해 클래스 가 암시 적으로로드 된 결과입니다 .

유사점 :

  • 모두 NoClassDefFoundErrorClassNotFoundException 런타임에 클래스의 가용성 관련이 있습니다.
  • 모두 ClassNotFoundExceptionNoClassDefFoundError자바 클래스 패스에 관련이 있습니다.

3

클래스 로더 sussystem 조치가 제공된 경우 :

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

이 기사는 차이점을 이해하는 데 도움이되는 기사입니다. http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

클래스를로드하는 동안 오류가 발생하면로드 되는 클래스 나 인터페이스를 (직접 또는 간접적으로) 사용하는 프로그램의 지점에서 LinkageError 서브 클래스의 인스턴스 가 발생해야합니다.

Java Virtual Machine이 확인 (§5.4.1) 또는 해결 (§5.4.3) 중에 클래스 C를로드하려고 시도하지만 (초기화 (§5.5) 아님) C로드를 시작하는 데 사용되는 클래스 로더 ClassNotFoundException 의 인스턴스를 throw하면 (자) , Java 가상 머신은 그 원인이 ClassNotFoundException 의 인스턴스 인 NoClassDefFoundError 의 인스턴스를 throw 할 필요 가 있습니다 .

따라서 ClassNotFoundExceptionNoClassDefFoundError 의 근본 원인입니다 .
그리고 NoClassDefFoundError링크 단계 에서 발생하는 특별한 유형의로드 오류 입니다.


2

가능한 한 가지 이유를 추가하십시오.

  • ClassNotFoundException : cletus가 말했듯이 상속 된 인터페이스 클래스가 클래스 경로에없는 동안 인터페이스를 사용합니다. 예를 들어, 서비스 제공자 패턴 (또는 서비스 로케이터 )은 존재하지 않는 클래스를 찾으려고 시도합니다.
  • NoClassDefFoundError : 주어진 클래스의 의존성을 찾을 수없는 동안 주어진 클래스를 찾았습니다

실제로는 오류자동으로 발생할 수 있습니다 . 예를 들어 타이머 작업을 제출하면 타이머 작업에서 오류 가 발생하지만 대부분의 경우 프로그램은 예외 만 잡습니다 . 그런 다음 타이머 메인 루프가 아무런 정보없이 종료됩니다. 정적 초기화 프로그램 또는 정적 변수의 초기화 프로그램에서 예외 가 발생하는 경우 NoClassDefFoundError와 유사한 오류는 ExceptionInInitializerError 입니다.


1

ClassNotFoundException 은 Class.forName () 또는 ClassLoader.findSystemClass () 또는 ClassLoader.loadClass () 메소드를 사용하여 문자열 이름으로 클래스를로드하도록 JVM에 지시하고 클래스 경로에 언급 된 클래스가없는 경우 발생하는 확인 된 예외입니다.

대부분의 경우이 예외는 필요한 JAR 파일로 클래스 경로를 업데이트하지 않고 응용 프로그램을 실행하려고 할 때 발생합니다. 예를 들어, JDBC 코드를 수행하여 데이터베이스 ieMySQL에 연결할 때이 예외가 발생했을 수 있지만 클래스 경로에 JAR이 없습니다.

NoClassDefFoundError 오류는 JVM이 코드 실행의 일부 (정상적인 메소드 호출의 일부 또는 새 키워드를 사용하여 인스턴스를 작성하는 일부) 인 특정 클래스를로드하려고 시도하고 해당 클래스가 클래스 경로에 없지만 프로그램을 실행하려면 컴파일해야하기 때문에 존재하지 않는 클래스를 사용하려고하면 컴파일 오류가 발생합니다.

아래는 간단한 설명입니다

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

자세한 내용은 ClassNotFoundException Vs NoClassDefFoundError에 대한 모든 것을 읽을 수 있습니다 .


0

새로 고침해야 할 때마다 다음을 반복해서 상기시킵니다.

ClassNotFoundException

클래스 계층

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

디버깅하는 동안

  1. 필수 jar, 클래스가 클래스 경로에서 누락되었습니다.
  2. 모든 필수 jar이 jvm의 클래스 경로에 있는지 확인하십시오.

NoClassDefFoundError

클래스 계층

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

디버깅하는 동안

  1. 올바르게 컴파일 된 클래스를 동적으로로드하는 데 문제가 있습니다.
  2. 정적 블록, 생성자, 종속 클래스의 init () 메소드에 대한 문제 및 실제 오류는 여러 레이어로 래핑됩니다. 특히 스프링을 사용할 때 최대 절전 모드에서 실제 예외가 래핑되고 NoClassDefError가 발생합니다.
  3. 종속 클래스의 정적 블록에서 "ClassNotFoundException"에 직면 할 때
  4. 클래스 버전에 문제가 있습니다. 이것은 v1을 사용하여 성공적으로 컴파일되고 v2가 관련 메소드 / vars가없는 런타임에로드되는 다른 jar / 패키지 아래에 동일한 클래스의 v1, v2의 두 가지 버전이있을 때 발생합니다.이 예외가 표시됩니다. [클래스 패스에 나타난 여러 jar에서 log4j 관련 클래스의 중복을 제거하여이 문제를 한 번 해결했습니다.]

-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입니다. A.class 파일을 제거하고 B.class 파일을 실행하면 Java Runtime System은 다음과 같이 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.