Java.Lang.NoClassDefFoundError 수정: 클래스 오류를 초기화할 수 없음

Mehvish Ashiq 2023년10월12일
  1. Java.Lang.NoClassDefFoundError: Could Not Initialize Class 오류가 있는 Java 프로그램
  2. Java.Lang.NoClassDefFoundError: Could Not Initialize Class 오류의 가능한 원인
  3. Java.Lang.NoClassDefFoundError: Could Not Initialize Class 오류를 근절하기 위한 솔루션
Java.Lang.NoClassDefFoundError 수정: 클래스 오류를 초기화할 수 없음

오늘은 또 다른 런타임 오류인 java.lang.noclassdeffounderror: could not initialize class에 대해 알아보겠습니다. 먼저 이 오류가 있는 Java 프로그램을 살펴보고 가능한 원인에 대해 논의하고 이 오류를 일으키는 코드 줄을 파악합니다.

마지막으로 이 오류를 제거하는 솔루션에 대해서도 알아보겠습니다.

Java.Lang.NoClassDefFoundError: Could Not Initialize Class 오류가 있는 Java 프로그램

예제 코드:

public class PropHolder {
  public static Properties prop;

  static {
    // write code to load the properties from a file
  }
}

예제 코드:

import java.util.Properties;

public class Main {
  public static void main(String[] args) {
    // set your properties here
    // save the properties in a file
    //  Referencing the PropHolder.prop:
    Properties prop = PropHolder.prop;
    // print the values of all properties
  }
}

여기에는 PropHolderMain이라는 두 개의 .java 클래스가 있습니다. PropHolder 클래스는 지정된 파일에서 속성을 로드하고 Main 클래스는 속성을 설정하고 파일에 저장합니다.

또한 PropHolder 클래스의 prop 변수를 참조하여 모든 속성 값을 인쇄합니다.

이 Java 코드는 로컬 컴퓨터에서 실행할 때는 제대로 작동하지만 일부 스크립트를 사용하여 Linux 서버에 배포할 때는 작동하지 않습니다. 왜 그래야만하지? 이유를 알아 봅시다.

Java.Lang.NoClassDefFoundError: Could Not Initialize Class 오류의 가능한 원인

첫째, java.lang.NoClassDefFoundError가 발생하는 것은 클래스가 누락되었음을 의미하는 것만이 아니라는 점을 기억하십시오. 그렇다면 java.lang.ClassNotFoundException이 발생합니다.

또한 바이트 코드(.class)가 누락되었음을 의미하지 않습니다(이 경우 java.lang.NoClassDefFoundError: classname과 같은 오류가 발생함).

따라서 서버에서 java.lang.noclassdeffounderror: 클래스를 초기화할 수 없습니다 오류는 클래스 파일을 찾을 수 없음을 의미합니다. 아래에 나열된 여러 가지 이유로 인해 발생할 수 있습니다.

  1. 문제는 static 블록(정적 이니셜라이저라고도 함)에 있을 수 있습니다. 잡히지 않은 예외와 함께 나타나며 클래스를 로드하려고 시도하는 실제 ClassLoader까지 발생 및 전파됩니다.

  2. 예외가 정적 블록으로 인한 것이 아닌 경우 PropHolder.prop라는 정적 변수를 생성하는 동안일 수 있습니다.

  3. 지정된 Java CLASSPATH에서 Class를 사용할 수 없을 수 있습니다.

  4. MANIFEST 파일의 ClassPath 속성에 Class가 정의되지 않은 상태에서 jar 명령을 사용하여 Java 프로그램을 실행했을 수 있습니다.

  5. 이 오류는 CLASSPATH 환경 변수를 재정의하는 시작 스크립트로 인해 발생할 수 있습니다.

  6. 또 다른 이유는 종속성이 없기 때문일 수 있습니다. 예를 들어 NoClassDefFoundErrorjava.lang.LinkageError의 하위 클래스이기 때문에 기본 라이브러리를 사용하지 못할 수 있습니다.

  7. 정적 초기화 실패로 인해 NoClassDefFoundError가 발생했을 가능성이 있으므로 log 파일에서 java.lang.ExceptionInInitializerError를 찾을 수도 있습니다.

  8. J2EE 환경에서 작업하는 경우 다른 ClassLoaders에서 Class의 가시성으로 인해 java.lang.NoClassDefFoundError 오류가 발생할 수 있습니다.

  9. 간혹 JRE/JDK 버전 오류로 인해 발생하는 경우가 있습니다.

  10. 예를 들어 OpenJDK 버전 8.x.x를 사용하여 시스템에서 무언가를 컴파일할 때도 발생할 수 있습니다. 푸시/커밋하지만 다른 사람이 JAVA_HOME을 일부 11.x JDK 버전으로 구성했습니다.

    여기에서 ClassNotFoundError, NoClassDefFoundError 등을 얻을 수 있습니다. 따라서 프로그램이 컴파일된 JDK를 확인하는 것이 좋습니다.

Java.Lang.NoClassDefFoundError: Could Not Initialize Class 오류를 근절하기 위한 솔루션

우리의 경우 클래스를 읽으려고 할 때 클래스 정의를 읽는 동안 ClassLoader에서 오류가 발생했습니다. 따라서 정적 초기화 안에 try-catch 블록을 넣으면 문제가 해결됩니다.

그곳에서 일부 파일을 읽으면 로컬 환경과 다를 수 있음을 기억하십시오.

예제 코드:

// import libraries
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

// PropHolder Class
public class PropHolder {
  // static variable of type Properties
  public static Properties prop;

  // static block, which loads the properties
  // from the specified file
  static {
    try {
      InputStream input = new FileInputStream("properties");
      prop = new Properties();
      prop.load(input);

    } catch (FileNotFoundException ex) {
      Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
    }
  } // end static block
} // end PropHolder class

위의 클래스에서 정적 블록에서 사용하는 속성 유형의 prop라는 정적 변수를 만들었습니다. 정적 블록 내에서 파일 시스템의 지정된 파일에서 입력 바이트를 가져오는 FileInputStream 객체를 생성했습니다.

다음으로 지정된 파일에서 속성을 로드하는 데 사용되는 Properties 클래스의 생성자를 호출하여 prop 변수를 초기화했습니다. 이 정적 블록은 애플리케이션을 실행한 후에만 실행된다는 점을 기억하십시오.

예제 코드:

// import libraries

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

// Main Class
public class Main {
  // main()
  public static void main(String[] args) {
    /*
    instantiate the Properties class, set various
    properties and store them in a given file
     */
    Properties prop = new Properties();
    prop.setProperty("db.url", "localhost");
    prop.setProperty("db.user", "user");
    prop.setProperty("db.password", "password");
    try {
      OutputStream output = new FileOutputStream("properties");
      prop.store(output, null);
    } catch (FileNotFoundException ex) {
      Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
    }

    /*
    reference the `PropHolder.prop` to access the values of
    the properties that we set previously
     */
    Properties obj = PropHolder.prop;
    System.out.println(obj.getProperty("db.url"));
    System.out.println(obj.getProperty("db.user"));
    System.out.println(obj.getProperty("db.password"));
  } // end main()
} // end Main

Main 클래스에서 Properties 클래스를 인스턴스화하여 다양한 속성에 대한 값을 설정하고 지정된 파일에 저장합니다. 다음으로 PropHolder.prop를 참조하여 db.url, db.userdb.password 속성 값에 액세스하고 프로그램 출력 콘솔에 다음과 같이 인쇄합니다.

출력:

localhost
user
password
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

관련 문장 - Java Error