로컬에서 잘 돌아가는데도 불구하고 서버에 올렸을 때 Source -> Build -> Deploy 과정이 전부 성공했음에도 불구하고 접속이 되지않아 로그를 열어 스텍 트레이스를 확인하였다.
확인 결과
java.lang.IllegalStateException: Failed to introspect Class from ClassLoader 에러가 발생하였다.
발생한 에러로는 JSONException을 찾을 수 없다는 에러였다.
org.json을 임포트 한게 하니라 스프링프레임워크 컨피규레이션 프로세서에 있는 Json을 import해서 에러를 뱉는 것이었다.
해당 에러에 대한 원인은 다음과 같았다.
java.lang.NoClassDefFoundError: org/springframework/boot/configurationprocessor/json/JSONException
java.lang.ClassNotFoundException: org.springframework.boot.configurationprocessor.json.JSONException
1. NoClassDefFoundError, ClassNotFoundException이란?
NoClassDefFoundError
JVM이 클래스 정의에 대한 내부 클래스 정의 데이터 구조를 찾아서 찾지 못했음을 나타낸다.
-> 컴파일 환경에서는 클래스 참조가 되었지만 런타임(실행) 환경에서는 해당 클래스를 찾을수 없는 경우에 발생한다고 한다.(개발보단 운영중에 많이 생긴다고 합니다.)
ClassNotFoundException
클래스가 클래스 경로에서 발견되지 않음. 클래스 정의를 로드하려고했지만 클래스가 클래스 경로에 존재하지 않았음
-> 컴파일 시 클래스 로더가 class를 찾을 수 없는 경우 발생합니다. 즉 참조하는 jar 파일이나 class 파일이 class path에 없는 경우 발생
위 사진을 보면 컴파일 단계에서 Class A는 Class B, Class C에 의해 인스턴화된 클래스로 생성되어있다. 이후
런타임 단계에서 Classpath에서 Class C가 없어진다면 JVM이 Class C를 로드할 수 없기 때문에 NoClassDefFoundError가 발생한다.(왜 없어질까..? 인식을 못하는 것이다. local에서는 인식되었으나 AWS 서버에선 인식하지 못한것)
2. 해결 방법
로컬에서는 잘 실행되던 서버가 AWS에 올라가면 에러를 내뿜고 로드할 수 없다고 하는걸까?
글쓴이는 JSON객체를 만들기 위해
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
일반적으로 다음과 같은 라이브러리를 import해서 사용하고 있었다.
그리고 JSON을 사용할 때 Unhandled exception: org.springframework.boot.configurationprocessor.json.JSONException 오류로 인해 해당 JSON클래스를 불러오는 모든 메소드에 throws JSONException을 추가하였다.
모든 throws JSONException을 추가하여 적용한 방법은 결국 local에서는 잘 돌아가지만 AWS에서 돌아가지 않는 근본적인 문제가 발생한다.
import org.json.JSONException;
import org.json.JSONObject;
따라서 다음과 같이 바꿔주면 Unhandled exception 에러도 나지 않고 서버에서도 오류가 나지 않는다.
https://mvnrepository.com/artifact/org.json/json/20200518
위 사이트에 접속하여 의존성을 확인하여 맞는 의존성을 로드한다.
Gradle
implementation group: 'org.json', name: 'json', version: '20200518'
Maven
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
springframework.boot.configurationprocessor은 무엇이고 왜 서버에서 에러가 났을까..
이 부분에 대해 공부하려고 정말 많은 레퍼런스를 봤는데 잘 나와있는 문서가 없었다. 아시는 분들은 알려주시면 감사합니다..
springframework.boot.configurationprocessor에서 로드한 JSON은 서버에서 런타임시 에러 발생..
org.json에서 로드한 일반 JSON은 잘 돌아간다.
springframework의 모듈도 classloader에 올라갈텐데 왜 에러가 나는지 모르겠다.
Reference
https://docs.oracle.com/javase/8/docs/api/java/lang/NoClassDefFoundError.html
'개발 > Spring boot' 카테고리의 다른 글
[Spring boot] JPA 기본 키 생성 전략(AUTO, IDENTITY, SEQUENCE, TABLE, UUID) (0) | 2023.03.06 |
---|---|
[Spring boot] Spring Boot Configuration Annotation Processor not confiugred (0) | 2023.02.25 |
Spring boot - Jasypt를 사용한 프로퍼티 암호화하기 (0) | 2022.09.28 |