개요
패키지 Build 중 발생한 에러.
PesApplicationTests > contextLoads() FAILED java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:98
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.BeanCreationException at BeanDefinitionValueResolver.java:342
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.BeanCreationException at BeanDefinitionValueResolver.java:342
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
Caused by: java.lang.UnsupportedClassVersionError at ClassLoader.java:-2
Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
Caused by: java.lang.UnsupportedClassVersionError at ClassLoader.java:-2
원인
UnsupportedClassVersionError 에러는 현재 JVM 버전보다 높은 버전의 클래스 파일을 읽으려고 할 때 발생한다.
특정 클래스 파일이 해당 Java 버전에서 지원하지 않는 기능을 사용하고 있기 때문에 해당 에러가 발생했다고 예상해 볼 수 있다.
방안
- 현재 사용 중인 Java 버전 확인
- 프로젝트 빌드 설정 확인 (sourceCompatibility)
- 현재 버전에서 지원하지 않는 기능을 사용하는 클래스 파일을 찾아 수정
해결 시도(실패)
각 JDK Version마다 Bytecode Major Version이 매핑된다. 현재 Java 8을 사용중이기 때문에 Bytecode Major Version 52.0에 매핑된다.
그렇다면 현재 53.0 이상의 Bytecode Version을 사용하고 있는 클래스를 찾으면 된다!
Java 1.0 | 45.0 |
Java 1.1 | 45.3 |
Java 1.2 | 46.0 |
Java 1.3 | 47.0 |
Java 1.4 | 48.0 |
Java 5 | 49.0 |
Java 6 | 50.0 |
Java 7 | 51.0 |
Java 8 (현재 버전) | 52.0 |
Java 9 | 53.0 |
Java 10 | 54.0 |
Java 11 | 55.0 |
Java 12 | 56.0 |
Java 13 | 57.0 |
Java 14 | 58.0 |
Java 15 | 59.0 |
Java 16 | 60.0 |
Java 17 | 61.0 |
Java 18 | 62.0 |
ChatGPT의 도움을 받아서 Bytecode Major Version 53이상을 사용하는 클래스 파일을 검색하는 명령어를 만들었다.
find . -name "*.class" -exec bash -c 'major_version=$(javap -v {} | grep "major version" | awk "{print \$3}"); if [ "$major_version" -ge 53 ]; then echo {}; fi' \;
테스트를 위해서 Bytecode Major Version 52(Java 8) 이상을 사용하는 클래스를 검색해보았다.
내가 만든 클래스 파일들이 줄줄이 잘 나오는 것을 확인할 수 있다.
$ find . -name "*.class" -exec bash -c 'major_version=$(javap -v {} | grep "major version" | awk "{print \$3}"); if [ "$major_version" -ge 52 ]; then echo {}; fi' \;
./out/test/classes/co/pes/AdminboardApplicationTests.class
./out/production/classes/co/pes/ServletInitializer.class
./out/production/classes/co/pes/PesApplication.class
./out/production/classes/co/pes/common/pagination/Paging.class
./out/production/classes/co/pes/common/pagination/Paging.class
./out/production/classes/co/pes/common/config/JspConfig.class
./out/production/classes/co/pes/common/config/SHA512Config.class
./out/production/classes/co/pes/common/config/JspConfig.class
./out/production/classes/co/pes/common/config/WebMvcConfig.class
./out/production/classes/co/pes/common/SessionsUser.class
./out/production/classes/co/pes/common/exception/BusinessLogicException.class
./out/production/classes/co/pes/common/exception/ExceptionCode.class
...
하지만 53 버전 이상의 클래스 파일을 검색했을 때는 나오지 않았다. 내가 생성한 클래스에서는 문제가 없는 것이다.
해결
실제 원인은 간단한 것이었다... 기존에는 MariaDB를 사용중이었는데, 요구사항이 변경되면서 Oracle로 DB를 변경해야 했었다.
이 때 oracle11을 의존하는 것이 문제였다.
현재 Java8을 사용중이기 때문에 Java8 전용인 oracle8을 의존하도록 build.gradle 수정해주었고 이후 패키지 Build가 정상적으로 진행되었다.
dependencies {
...
runtimeOnly 'com.oracle.database.jdbc:ojdbc8' // ojdbc11 -> ojdbc8로 변경
...
}
이 외에도 해당 에러를 해결하는 방법은 다양하다. 다른 해결 방안은 아래 참조 링크를 참고하시면 좋을 것 같다.
참조