본문 바로가기
에러 기록/배포 에러

java.lang.NoClassDefFoundError: 외부 라이브러리

by 샤샤샤샤 2023. 10. 22.

리눅스 배포시 java.lang.NoClassDefFoundError: 외부 라이브러리 에러가 발생한다.

몇시간째 구글링한 결과 크게 2가지로 나뉘는 것을 알았다.

 

1. 버전이 맞지 않은 경우.

나같은 경우는 gradle을 통해 외부 라이브러리를 추가했다.

만약 서로 의존하는 라이브러리간 버전이 맞지 않으면 참조할수 없어 오류가 발생할수 있다.

따라서 버전을 맞춰주면 해결됨

 

2. classpath 가 옳게 설정되지 않은 경우.

gradle 을 통해 불러온 라이브러리는 /Users/${USERNAME}/.gradle/caches/modules-2/files-2.1/${packageName}/${libname} 에 저장된다.
따라서 소스 코드 내부에서 외부 라이브러리를 임포트해서 사용할때, 라이브러리가 직접적으로 저장되어 있는 해당 위치에서 소스를 가져오도록 설정해줘야 한다. 이 경로가 바로 classpath다.

본래는 Manifest 라는 JAR(Java Archive) 파일이나 WAR(Web Archive) 파일과 같은 Java 압축 파일 형식에 포함된 메타데이터 파일을 통해 설정해줄수 있다. 메니페스트는 이러한 압축 파일 내에 어떤 파일이 포함되어 있는지, 어떤 메인 클래스를 실행해야 하는지, 어떤 종속성을 갖고 있는지, 어떤 서명이 있는지 등의 정보를 포함하고 있어 옳바르게 설정해줄수 있다. Gradle 의 경우에는 jar 태스크를 만들어

jar {
    manifest {
        attributes 'Main-Class': 'org.example.TraderController'
    }
 }

과 같은 형식으로 설정해줄수 있다.

 

그러나 보다시피 나는 jar 태스크를 설정하는 방법을 몰라서 직접 Linux 에서 명령어를 통해 컴파일시 classpath 와 런타임시 classpath를 직접 설정해주었다.

 

javac -cp {라이브러리가 있는 경로} {.java 파일 경로}

해당 명령어로 컴파일시 클래스 패스를 설정해줄수 있다.

java -cp {라이브러리가 있는 경로} {.java 파일 경로}

해당 명령어로 런타임시 클래스 패스를 설정해줄수 있다.

 

소요시간 : 거의 5시간