java为什么javaassist仅在项目中使用lambda时加载Entitymanager时抛出无效的常量类型:18
在发布这个具体问题之前,我阅读了很多QnA。大多数javaassist无效常量18问题的答案都是为了升级javaassist库。在这些QnA的基础上,我还在我的项目中将lib升级到最新版本,它真的很有效。但我不理解以下内容,如果可以的话,我需要有人帮助我提供一些见解:
这里是环境
当前版本: JDK:build 1.8.0_92-b14
javaassist:3.14.0。GA
冬眠:3.5.1-决赛
构建用途:Ant
截止日期项目代码中没有lamda或流。 代码生成并成功运行。目前没有问题强>
现在,这里是我使用lambda和Streams时发生的情况
案例1:无javaassist升级 现在,只要我在同一个项目中介绍任何Lamda和Stream,然后 在服务器启动期间抛出异常,特别是在Spring容器启动时。 奇怪的是,根据IoC容器中显示的日志,具有Lambda和Stream的类确实在没有问题的情况下得到了初始化,但是一个试图初始化EntityManager的现有bean得到了运行时异常。 根据QnA的一条评论
案例2:一旦java assist升级到最新版本(或高于3.17.0-GA的任何版本),一切正常
问:为什么在有lambda的类中不抛出异常,而在项目没有任何lambda/流时,现有hibernate的实体管理器工作正常?引发此异常时已成功加载lambda的Infact Bean,并位于容器内
有人能解释一下吗
以下是完整的错误跟踪:
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'ldbEntityManagerFactory' defined in ServletContext resource
[/WEB-INF/spring/JPA.xml]: Invocation of init method failed; nested
exception is java.lang.RuntimeException: Error while reading
file:/C:/home/tcserver/profiles/instance/webapps/app/WEB-INF/classes
-------deleted--------------
... 25 more
**Caused by: java.io.IOException: invalid constant type: 18**
at javassist.bytecode.ConstPool.readOne(ConstPool.java:1090)
at javassist.bytecode.ConstPool.read(ConstPool.java:1033)
at javassist.bytecode.ConstPool.<init>(ConstPool.java:149)
at javassist.bytecode.ClassFile.read(ClassFile.java:764)
at javassist.bytecode.ClassFile.<init>(ClassFile.java:108)
atorg.hibernate.ejb.packaging.AbstractJarVisitor.checkAnnotationMatching(Abs
tractJarVisitor.java:236)
atorg.hibernate.ejb.packaging.AbstractJarVisitor.executeJavaElementFilter(Ab
stractJarVisitor.java:202)
aorg.hibernate.ejb.packaging.AbstractJarVisitor.addElement(AbstractJarVisito
r.java:163)
aorg.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(Exploded
JarVisitor.java:101)
----DELETED---
g.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:614)
... 31 more
# 1 楼答案
它无法创建EntityManager实例,因为管理器正在加载的类失败。那么这就不是管理器的javassist问题,而是它所加载的类的问题。因此,完全有可能有一次创建管理器没有问题(在使用中没有lambdas)和一次失败(使用lambdas)。错误消息表明旧的javaassist版本不理解InvokedDynamic指令,这意味着它是Java7之前的版本。只是在Java7中,java本身没有使用该指令,这使得问题完全可能只出现在java8代码中。Lambda正在利用InvokedDynamic