- 에러 원인 찾는 방법
- neseted exception: error 원인 부분
- Causerd by : 아래로 내려갈수록 추상화 된 에러 메시지가 점점 구체화가 된다.
1. 에러 문구
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myMath' defined in file [/Users/taewan/Documents/junsukBE/ch2/target/classes/com/fastcampus/aop/MyMath.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; nested exception is java.lang.ExceptionInInitializerError
....
Caused by: org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; nested exception is java.lang.ExceptionInInitializerError
....
Caused by: java.lang.ExceptionInInitializerError
....
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1d548a08
....
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1d548a08
2. 원인 에러
- nested exception is org.springframework.aop.framework.AopConfigException: Unexpected AOP exception;
aop 부분에서 문제가 발생 - Caused by: java.lang.ExceptionInInitializerError
해당 클래스의 static 블록에서 예외가 발생, 추상적인 에러문구 - module java.base does not "opens java.lang" to unnamed module
이 오류는 Java 9 이후부터 적용되는 모듈 시스템(Module System)과 관련된 오류.
Java 9부터는 클래스패스 대신 모듈 시스템을 사용하게 되어서 이러한 오류가 발생
3. 해결
- 현재 사용하고 있는 java -v이 java17
- java 17 -> java 11 로 downgrade 후, pom.xml에 11로 변경, target package 지운후, 재시작 -> 정상 작동
4. Warning 문구
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/Users/taewan/.m2/repository/org/springframework/spring-core/5.0.7.RELEASE/spring-core-5.0.7.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
5. 원인
- Spring에서 illegal reflective access 경고문 해결
- 결론적으로 경고일 뿐 프로그램의 동작을 방해하는 예외나 에러가 아니다.
- For full JDK 9+ support, please upgrade to Spring Framework 5.1+ / Spring Boot 2.1+.
이는 JDK 9 이상의 버전에서 JDK API에 의해 발생하는 문구기 때문에 이를 완전히 지원하려면 스프링 프레임워크 버전을 5.1 이상으로, 스프링 부트 버전은 2.1 이상으로 올리면 해결된다.
6. 해결
- 2가지 방법중 1가지 만 수행하면 된다.
1. dependency에 직접 springframework version을 변경
<!--
warning 부분 오류 해결
1. dependency의 version을 변경하기
2. 실제 properties의 spring version을 5.2.21.RELEASE로 변경 -> 이게 향후 spring version에 의존하는 dependency를 위해 더 나은 선택일 것 같다.
-->
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.21.RELEASE</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.21.RELEASE</version>
</dependency>
2. 실제 properties의 spring version을 5.2.21.RELEASE로 변경
-> 이게 향후 spring version에 의존하는 dependency를 위해 더 나은 선택일 것 같다.
<properties><!-- 중요 : key-value로 되어 있음. key<java-version>, value : 1.6 -> 사용 방법 ${java-version} -> properties 내부값이 자동으로 변경됨}-->
<java-version>11</java-version>
<org.springframework-version>5.2.21.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- warning 부분 오류 해결
1. dependency의 version을 변경하기
2. 실제 properties의 spring version을 5.2.21.RELEASE로 변경 -> 이게 향후 spring version에 의존하는 dependency를 위해 더 나은 선택일 것 같다.
-->
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
7. 다시 java 17 사용
- 에러 근본 원인
2가지 에러가 겹쳐진 복합 문제
- java 17이 근본적인 문제가 아니였고 springframework의 spring-context의 너무 낮은 version의 문제
- 자바 17로 compile 되는 문제
- 그래서 compile version을 17로 수행한 결과 다른 error 가 나왔다.
7.1. spring-context의 너무 낮은 version의 문제 해결 후 에러 코드
- java 17 version
- compile 된 module의 자바 version
- pom.xml의 compile java version 설정
<properties>
<!--Project structure의 modules의 version을 설정하는 것-->
<java-version>17</java-version>
<org.springframework-version>5.2.21.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
- 에러 코드
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file [/Users/taewan/Documents/junsukBE/ch2/target/classes/com/fastcampus/aop/AopMain.class]; nested exception is org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet: file
7.2. 해결방안
- 최신 버전의 ASM 라이브러리를 사용 (권장) - 아직 안해봄
- 컴파일러의 설정을 변경하여 더 낮은 버전의 클래스 파일을 생성 (사용)
- 해당 클래스 파일의 버전을 확인하여 ASM 라이브러리에서 지원하는 범위 내로 수정
<properties>
<!--이게 compile하는 version인데 11로 해야지 현재 사용하는 aop 기능을 수행할 수 있다.
현재 사용하고 있는 java version은 17이다. 하지만 compile만 downgrade해서 문제없이 작업을 수행 가능할 수 있게 되었다.
-->
<!--Project structure의 modules의 version을 설정하는 것-->
<java-version>12</java-version>
<org.springframework-version>5.2.21.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
- 정상 동작한다.