在发布此特定问题之前,我阅读了许多QnA。回答了大多数javaassist无效常量18问题,以升级javaassist lib。基于这些QnA,我还在项目中将lib升级到了最新版本,并且确实有效。但是我不理解以下内容,如果可以,请得到他人的帮助以提供一些见解:
这是环境
当前版本: JDK:内部版本1.8.0_92-b14
javaassist:3.14.0.GA
休眠:3.5.1-最终
构建用途:蚂蚁
截止日期项目在代码中没有lamda或流。代码生成并成功运行。到目前为止没有问题。
现在,这就是我使用Lambda和Streams时发生的情况。
情况1:没有立即进行javaassist升级,当我在同一项目中引入任何Lamda和Stream时,特别是在Spring容器启动时,特别是在服务器启动期间跟随异常抛出。奇怪的是,根据IoC容器中显示的日志,具有Lambda和Stream的类确实已初始化而没有问题,但是尝试启动EntityYmanager的现有bean之一获得了运行时异常。基于QnA谈论的其中一项评论
情况2:将Java助手升级到最新版本(或高于3.17.0-GA的所有版本)后,一切正常。
问题:为什么在具有Lambda的类上不抛出Exception,但是当项目没有任何Lambda / stream时,现有的休眠的Entitity Manager可以正常工作?引发此Exception时,具有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.(ConstPool.java:149) at javassist.bytecode.ClassFile.read(ClassFile.java:764) at javassist.bytecode.ClassFile. (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
blackdrag.. 6
由于管理器正在加载的类失败,因此无法创建EntityManager实例。然后,管理器不是Javassist问题,而是管理器加载的类。因此,完全有可能一次创建管理器都没有问题(使用中没有lambda),一次失败(使用lambda)。错误消息表明旧的Javaassist版本不理解invokedynamic指令,这意味着它是Java7之前的版本。只有在Java7中,java本身才不使用指令,这使得仅在java8代码中出现问题的可能性就完全成立了。而且lambda正在利用invokedynamic。
由于管理器正在加载的类失败,因此无法创建EntityManager实例。然后,管理器不是Javassist问题,而是管理器加载的类。因此,完全有可能一次创建管理器都没有问题(使用中没有lambda),一次失败(使用lambda)。错误消息表明旧的Javaassist版本不理解invokedynamic指令,这意味着它是Java7之前的版本。只有在Java7中,java本身才不使用指令,这使得仅在java8代码中出现问题的可能性就完全成立了。而且lambda正在利用invokedynamic。