java.lang.NoClassDefFoundError : 클래스 XXX를 초기화 할 수 없습니다


165
public class PropHolder {
  public static Properties prop;

  static {
    //code for loading properties from file
  }
}

// Referencing the class somewhere else:
Properties prop = PropHolder.prop;

class PropHolder내 자신의 클래스입니다. 클래스는 기본 클래스와 동일한 JAR 파일에 있습니다. 따라서 클래스 경로에서 JAR이 누락되어서는 안됩니다.

로 JAR 파일을 살펴보면 나열된 파일을 jar tf myjarfile볼 수 있습니다 PropHolder.class.

Btw : 코드가 로컬 컴퓨터에서 제대로 실행되고 있습니다. 그러나 일부 스크립트를 사용하여 Linux 서버에 배포하면 작동하지 않았습니다. 따라서 코드의 문제가 아니라고 생각합니다. 그러나 어떤 이유로 든. 배포 프로세스는 추적하기가 매우 어렵습니다.

무엇이 문제 일 수 있습니까?


jar 패키지의 적절한 디렉토리 구조가 클래스 패키지와 일치합니까?
John B

어떤 출처를 볼 필요가 있습니다. 많은 것들이 이것을 일으킬 수 있습니다. 예를 들어, 'package'문이지만 파일이 실제로 해당 경로에 있지 않음
jcomeau_ictx

3
한 가지 원인은 초기화 중 예외입니다. 다른 오류 출력이 있습니까?
Michael Brewer-Davis

답변:


211

최선의 방법은 여기에 문제가 있다는 것입니다.

static {
    //code for loading properties from file
}

잡히지 않은 예외가 발생하여 클래스를로드하려고 시도하는 실제 ClassLoader까지 전파 된 것처럼 보입니다. 그래도이를 확인하려면 스택 추적이 필요합니다.

PropHolder.prop정적 변수를 만들 때 또는 발생했습니다 .


나는 똑같은 문제에 직면 해왔다. static문제 때문이라고 확신합니다 . 문제를 해결하려면 어떻게해야합니까?
독사

1
static블록 에서 어떤 예외가 발생했는지 식별해야합니다 . 디버깅하려면 try/catch(Exception e)전체 블록을 둘러싼 다음 예외를 기록하십시오. 해당 예외를 수정해야합니다. 일반적으로 예외가 기록되지만 그것의 존재가 초기 발생할 수 있습니다 클래스 로딩 중에 기록 있기 때문에 찾기 어려울 수 있습니다
존 빈트

예, 코드를 try catch차단 한 상태로 유지 했습니다 Failed to initialize ClassA. 나는 그것이 문제라고 생각합니다 JVM. 시스템을 다시 시작한 후 모든 것이 제대로 작동했습니다. 나중에 시스템을 다시 시작하지 않고이 문제를 어떻게 해결하고 간단한 해결 방법으로 문제를 해결합니까?
독사

ClassA를 초기화하지 못하면 다른 것의 부작용입니다. cause가능한 경우 를보고 싶을 것 입니다. A NoClassDefFoundError는 항상 다른 오류와 관련이 있으므로 로그에서 오류를 찾거나보다 적절하게 로그해야합니다 (파일 시스템의 새 파일에 강제로 로깅하는 것과 같이).
John Vint

Java가 CouldNotInitializeStaticPartOfClassError 또는 기타 오류를 발생시키는 경우 더 쉽게 추적 할 수 있습니다. 그러면 개발자로서 우리는 어디를 볼지 알게 될 것입니다.
Maarten

126

당신은 java.lang.NoClassDefFoundError클래스가 누락되었다는 것을 의미하지는 않습니다 (이 경우에는을 얻습니다 java.lang.ClassNotFoundException). 클래스를 읽으려고 할 때 클래스 정의를 읽는 중에 클래스 로더에 오류가 발생했습니다.

정적 이니셜 라이저 안에 try / catch를 넣고 예외를 살펴보십시오. 일부 파일을 읽고 로컬 환경과 다른 경우 문제의 원인 일 수 있습니다 (파일을 찾을 수 없거나 권한이없는 것일 수 있음).


1
한 가지 클레임은 NoClassDefFoundError가 ClassNotFoundException을 암시하지 않더라도 여전히 NoClassDefFoundError의 원인 일 수 있다는 것입니다.
John Vint

1
buf 만약 당신이 ClassNotFoundException을 가지고 있다면 ClassLoader는 클래스를로드하려고 시도하지 않을 것입니다.
jeha

4
클래스가 발견되지 않은 다른 클래스를로드 할 수 있습니다. 해당 인스턴스의 원인은 여전히 ​​ClassNotFoundException입니다.
John Vint

1
나는 분명히 예외를 의미
John Vint

1
JAR (보고 된 클래스가 속한)가 포함되어 있는지 확인하는 데 약 20 분이 소요되었으므로 여기에서 실제로 도움이되었습니다. 내가 잘못된 방향을 찾고 있다는 것을 깨달았을 때, 일부 주석 클래스가 누락되어 보일 것으로 쉽게 이해했습니다 @Stateless. 팁 고마워!
RAM237

33

NoClassDefFoundError는 정적 블록 내부에서 무엇이 잘못되었는지에 대한 단서를 제공하지 않습니다. 정적 {...} 초기화 코드 안에 항상 이와 같은 블록을 두는 것이 좋습니다.

static {
  try {

    ... your init code here

  } catch (Throwable t) {
    LOG.error("Failure during static initialization", t);
    throw t;
  }
}

kotlin에서 어떻게해야합니까?
Marlon

힌트를 주셔서 감사합니다. 제 경우에는 정적 라인 초기화에 대해 NPE를 얻었습니다.
Abhishek

3

나는 같은 예외가 있었는데, 이것이 내가 문제를 해결 한 방법입니다.

전제 조건 :

  1. 다른 클래스를 확장 한 Junit 클래스 (및 테스트)

  2. ApplicationContext는 프로젝트를 초기화하는 스프링을 사용하여 초기화되었습니다.

  3. @Before 메소드에서 애플리케이션 컨텍스트가 초기화되었습니다.

해결책:

부모 클래스에도 응용 프로그램 컨텍스트 내에서 초기화 된 일부 클래스가 필요했기 때문에 @BeforeClass 메서드에서 응용 프로그램 컨텍스트를 초기화하십시오.

이것이 도움이되기를 바랍니다.


2

위에서 언급했듯이 이것은 여러 가지 일 수 있습니다. 제 경우에는 속성 파일에서 누락 된 항목에 의존하는 정적으로 초기화 된 변수가있었습니다. 속성 파일에 누락 된 항목을 추가하면 문제가 해결되었습니다.


1

며칠 전, 나는 당신과 같은 질문을 만났습니다. 모든 코드는 로컬 컴퓨터에서 제대로 실행되지만 오류 (noclassdeffound & initialize)가 나타납니다. 그래서 솔루션을 게시했지만 이유를 모르겠습니다. 단지 가능성을 높입니다. 누군가 John이 도움을 줄 수 있기를 바랍니다. @ John Vint 먼저, 나는 당신에게 내 문제를 보여줄 것입니다. 내 코드에는 정적 변수와 정적 블록이 있습니다. 이 문제를 처음 만났을 때 John Vint의 솔루션을 시도하고 예외를 잡으려고했습니다. 그러나 나는 아무것도 잡지 못했다. 그래서 정적 변수 (그러나 지금은 그것들이 같은 것을 알고 있기 때문에)라고 생각했지만 여전히 아무것도 찾지 못했습니다. 그래서 나는 리눅스 컴퓨터와 내 컴퓨터의 차이점을 찾으려고 노력합니다. 그런 다음이 문제는 한 프로세스에서 여러 스레드가 실행될 때만 발생한다는 것을 알았습니다 (그런데 리눅스 머신에는 더블 코어와 더블 프로세스가 있습니다). 즉, 동일한 프로세스에서 실행되는 두 가지 작업 (정적 블록 또는 변수가있는 코드를 사용하는 코드)이 있으면 잘못되지만 다른 프로세스에서 실행되면 둘 다 정상입니다. 리눅스 머신에서는

mvn -U clean  test -Dtest=path 

작업을 실행하려면 정적 변수가 컨테이너를 시작하거나 새 클래스 로더를 초기화하는 것이므로 jvm이 중지 될 때까지 유지되고 한 프로세스의 모든 작업이 중지 될 때만 jvm이 중지됩니다. 모든 작업은 새로운 컨테이너 (또는 클래스 로더)를 시작하고 jvm을 혼란스럽게 만듭니다. 결과적으로 오류가 발생합니다. 어떻게 해결해야합니까? 내 솔루션은 maven 명령에 새 명령을 추가하고 모든 작업을 동일한 컨테이너로 이동시키는 것입니다.

-Dxxx.version=xxxxx #sorry can't post more

이 문제를 이미 해결했을 수도 있지만 같은 문제를 해결하는 다른 사람들에게 도움이되기를 바랍니다.


또한 코드가 Linux 시스템에서 실행될 때 위의 오류를 따르십시오. 또 다른 문제 java.lang.ExceptionInInitializerError: null가 있습니다. 클래스 로더에서 클래스를 찾을 수 없거나 어떤 클래스를로드 해야할지 모른다는 것을 의미합니다. 당신은 그것을 만났습니까?
MonkeyKing

1

같은 예외가 있었지만 디버그 모드에서 실행하는 동안에 만 문제가 해결되었습니다 (3 일 후). build.gradle에서 : "multiDexEnabled true"가 defaultConfig 섹션에 설정되었습니다.

        defaultConfig {
    applicationId "com.xxx.yyy"
    minSdkVersion 15
    targetSdkVersion 28
    versionCode 5123
    versionName "5123"
    // Enabling multidex support.
    multiDexEnabled true
}

그러나 이것으로는 충분하지 않았습니다. 하지만 내가 바뀌었을 때 :

public class MyAppClass  extends Application 

에:

public class MyAppClass  extends MultiDexApplication 

이것은 그것을 해결했다. 이것이 누군가를 도울 수 있기를 바랍니다.


0

Android 프로젝트에서 작업중인 경우 Android 클래스에서 정적 메소드를 호출하지 않아야합니다. JUnit + Mockito 만 사용하고 있으므로 다른 프레임 워크가 문제를 완전히 피하는 데 도움이 될 수 있습니다.

내 문제는 Uri.parse(uriString)단위 테스트를위한 정적 초기화의 일부로 호출하는 것이 었습니다 . Uri 클래스는 Android API이므로 단위 테스트 빌드에서 찾지 못했습니다. 이 값을null 대신 하고 모든 것이 정상으로 돌아 왔습니다.


0

java.lang.NoClassDefFoundError 같은 문제가 발생했습니다 : 클래스 com.xxx.HttpUtils를 초기화 할 수 없습니다

static {
    //code for loading properties from file
}

그것은 환경 문제입니다. 그것은 application.yml 의 속성 이 잘못되었거나 비어 있음을 의미합니다 !


0

나는 같은 문제가 발생합니다. 아래와 같이 정적 블록에서 빈 객체를 초기화했습니다.

static {
    try{
        mqttConfiguration = SpringBootBeanUtils.<MqttConfiguration>getBean(MqttConfiguration.class);
    }catch (Throwable e){
        System.out.println(e);
    }
 }

내 bean obejct inition으로 인해 NPE가 발생했기 때문에 문제가 발생합니다. 따라서 정적 코드 블록을주의 깊게 확인해야한다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.