애플리케이션은 Spring 5 와 Mybatis 를 사용하는데 최근 JPA 사용을 늘리는 중이다.(spring boot 사용안함)
그런데 로컬에서는 잘 실행되던 것이 개발서버에 올리니 ClassFile 에러가 발생했다.
로그를 보면 entityManagerFactory 를 Bean으로 생성하지 못해서 발생한 문제였다.
해당 파일은 org.hibernate.boot.archive.scan.spi 안에 ClassFileArchiveEntryHandler 파일 내 toClassFile 를 실행하면서 IOException이 발생한 것이고 IOException 발생원인은 javassist 에서 'invalid constant type: 18'가 발생한게 원인이었다.
아래는 에러 내용이다
[11-25 17:32:40] [ERROR] [web.context.ContextLoader/312] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaEntityManagerFactory' defined in ServletContext resource [/WEB-INF/spring/root-context.xml]: Invocation of init method failed; nested exception is org.hibernate.boot.archive.spi.ArchiveException: Could not build ClassFile
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
...
Caused by: org.hibernate.boot.archive.spi.ArchiveException: Could not build ClassFile
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassFile(ClassFileArchiveEntryHandler.java:64) ~[hibernate-core-5.3.14.Final.jar:5.3.14.Final]
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:47) ~[hibernate-core-5.3.14.Final.jar:5.3.14.Final]
at org.hibernate.boot.archive.internal.ExplodedArchiveDescriptor.processDirectory(ExplodedArchiveDescriptor.java:143) ~[hibernate-core-5.3.14.Final.jar:5.3.14.Final]
at org.hibernate.boot.archive.internal.ExplodedArchiveDescriptor.processDirectory(ExplodedArchiveDescriptor.java:118) ~[hibernate-core-5.3.14.Final.jar:5.3.14.Final]
at org.hibernate.boot.archive.internal.ExplodedArchiveDescriptor.processDirectory(ExplodedArchiveDescriptor.java:118) ~[hibernate-core-5.3.14.Final.jar:5.3.14.Final]
...
Caused by: java.io.IOException: invalid constant type: 18
at javassist.bytecode.ConstPool.readOne(ConstPool.java:1023) ~[javassist-3.7.ga.jar:?]
at javassist.bytecode.ConstPool.read(ConstPool.java:966) ~[javassist-3.7.ga.jar:?]
at javassist.bytecode.ConstPool.<init>(ConstPool.java:127) ~[javassist-3.7.ga.jar:?]
stackoverflow에 다음의 내용을 발견했다.
So you are using a library which has a class parser which is not Java 8 compatible. Actually, this class parser even isn’t Java 7 compatible as this constant value is specified since Java 7. It just got away with that as ordinary Java code doesn’t use this feature in Java 7. But when interacting with code produced by different programming languages for the JVM, it could even fail with Java 7. |
내용을 보면 JAVA 8 에서 호환되지 않는 class parser가 있기 때문.
그래서 위의 문제를 javassist-3.18.2-GA 버전에서 해결했다는 댓글이 달려있었다.
With this fix: https://issues.jboss.org/browse/JASSIST-174javassist got support for this constant. So with 3.18.2-GA this error doesn't occur. |
해서 메이븐에 다음의 내용을 추가해서 실행했더니 정상 작동했다.
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.2-GA</version>
</dependency>
한가지 걸리는것은 해당 파일 업데이트 날짜가 2014년이란 점이다.
그래서 가장 최근 버전인 3.26.0-GA 를 추가했더니 위 에러가 다시 발생했다.
그래서 한단계 아래인 3.25.0-GA 를 했는데 다행히 이것은 된다.
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
끝.
참고:
https://blog.hippolab.com/56
https://stackoverflow.com/questions/30313255/reflections-java-8-invalid-constant-type
'공부 > 프로그래밍' 카테고리의 다른 글
[spring] LocalDateTime 주고받기(Response, Request) (0) | 2019.12.15 |
---|---|
[spring] 데이터 변수명 변경하여 전달하기 (@JsonProperty 사용) (0) | 2019.12.14 |
[docker] 공유된 volume 에 접근이 안될 때 (0) | 2019.11.02 |
[test] nGrinder 설치 및 테스트환경 구축(mac) (0) | 2019.10.26 |
[spring] @Value 활용(Field, Method, SqEL) (0) | 2019.10.20 |
댓글