본문 바로가기

개발/Spring boot

[Spring boot] configurationprocessor JSONException 에러

로컬에서 잘 돌아가는데도 불구하고 서버에 올렸을 때 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

http://daplus.net/java-java%EC%97%90%EC%84%9C-noclassdeffounderror%EA%B0%80-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C/

 

[java] Java에서 NoClassDefFoundError가 발생하는 이유는 무엇입니까? - 리뷰나라

NoClassDefFoundErrorJava 애플리케이션을 실행할 때을 받고 있습니다. 일반적으로 이것의 원인은 무엇입니까? 답변 이것은 코드가 의존하는 클래스 파일이 있고 컴파일 타임에 존재하지만 런타임에는

daplus.net

https://docs.oracle.com/javase/8/docs/api/java/lang/NoClassDefFoundError.html

 

NoClassDefFoundError (Java Platform SE 8 )

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found. The sear

docs.oracle.com

https://blog.aacii.net/134

 

ClassNotFoundException 과 NoClassDefFoundError

개요 우리는 자바 3rd-party 라이브러리(jar)를 사용할 때 보통 maven이나 gradle 같은 빌드 도구를 사용합니다. 빌드 도구들은 해당 라이브러리에 대한 의존적인 클래스나 라이브러리를 같이 컴파일

blog.aacii.net