熊伟
骑士
骑士
  • UID339
  • 粉丝3
  • 关注1
  • 发帖数21
  • 社区居民
  • 忠实会员
阅读:13236回复:1

关于5.0开发平台不能使用Java8的lambda表达式语法的解决方案(2)

楼主#
更多 发布于:2019-05-31 16:50
关于5.0开发平台不能使用Java8的lambda表达式语法的解决方案(2)

在上一篇中简单介绍了关于5.0开发平台不能使用Java8的lambda表达式语法的解决方案。之前由于事情较多,没有作进一步解释,这里对解决过程作一个详细记录

一、为什么不支持

要解决这个问题,首先要弄清楚为什么平台不支持java8的lambda语法。在使用lambda语法之后,平台报错(部分、重点):

Caused by: java.io.IOException: invalid constant type: 18 at com.sunsheen.jfids.javassist.bytecode.ConstPool.readOne(ConstPool.java:1027)
        at com.sunsheen.jfids.javassist.bytecode.ConstPool.read(ConstPool.java:970)
        at com.sunsheen.jfids.javassist.bytecode.ConstPool.<init>(ConstPool.java:127)
        at com.sunsheen.jfids.javassist.bytecode.ClassFile.read(ClassFile.java:723)
        at com.sunsheen.jfids.javassist.bytecode.ClassFile.<init>(ClassFile.java:110)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.checkAnnotationMatching(AbstractJarVisitor.java:243)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.executeJavaElementFilter(AbstractJarVisitor.java:209)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.addElement(AbstractJarVisitor.java:170)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:121)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:129)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:129)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:129)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:129)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.doProcessElements(ExplodedJarVisitor.java:87)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.getMatchingEntries(AbstractJarVisitor.java:146)
        at org.hibernate.ejb.packaging.NativeScanner.getClassesInJar(NativeScanner.java:128)
google搜索该问题的解决方案,可以知道是由于javassist 3.18以下的版本不支持在JDK1.8下运行

二、解决过程

弄清楚了为什么不支持,解决问题的思路就有了:将javassist更新到支持jdk1.8的版本
  • 如果是普通工程,直接将javassist替换为3.18以后的版本;
  • 如果是maven工程就更简单了,根据maven的依赖树,排除旧版本的依赖,手动引入新版的依赖;
  • 然而,开发平台为了锁定这些基础库的版本,修改了类路径,再引用修改后的路径。
所以,解决方案就是:修改支持java8的javassist版本,使得类路径保持一致,并使平台加载修改后的版本。
具体步骤为:

1、下载支持java8的javassist版本

javassist是一个开源的java字节码操作库,在github上有源码,下载地址https://github.com/jboss-javassist/javassist.git
这里我下载的是3.20版本

图片:1.png



2、修改类路径(包名),再打包

平台将修改后的javassist库打包到了hearken-base.jar包中,如图:

图片:2.png


因此,使用IDEA打开上面下载的官方javassist,修改包名,同时注意修改打包用到的结构描述文件MANIFEST.MF

图片:3.png


修改完成之后,再使用maven打包

图片:4.png




3、从hearken-base.jar包中剔除javassist包
  1. 先找到hearken集成开发平台下的hearken-base.jar包,在hearken-v5.0.0-win64\deploycontent\WebRoot\WEB-INF\lib目录下,复制到一个临时路径下
  2. 将复制的jar包,使用压缩文件解压
  3. 进入解压后的文件夹,删除目录hearken-base\com\sunsheen\jfids\javassist
  4. 图片:5.png


  5. 命令行进入hearken-base根目录,打包
//打包当前目录到hearken-base.jar中
jar cvf hearken-base.jar .

图片:6.png


打包完成后,会在当前目录生成一个新的hearken-base.jar包


4、添加依赖到构建路径

到目前为止,生成了两个jar包:

hearken.javassist-3.20.0-GA.jar //修改了类路径的支持java8语法的版本
hearken-base.jar //剔除了javassist后重新打的包
  • 如果只是针对一个项目,则将上诉两个jar包复制到平台第三方库目录下,加到构建路径中即可。但是这种方案有一个缺点:由于平台优先加载自带的jar包,所以部署到jboss上之后,会发现部署的hearken-base.jar不是刚刚我们重新打的包,需要手动复制到jboss部署目录下
  • 如果想要避免上诉问题,同时使得平台上的所有项目都支持java8语法,可以将上诉两个文件,复制到平台hearken-v5.0.0-win64\deploycontent\WebRoot\WEB-INF\lib目录下,该目录下的所有文件会在部署到jboss上时自动复制到部署目录下。但是,这种方式的缺点是:如果某个项目使用了修改后的hearken-base.jar包,则会导致两边的需求都不能满足(这时这篇文章的作用就出来了)。
5、启动

这时,再启动试试呢,是不是惊喜发现启动不再报上面那凡人的错了

图片:7.png


三、结语

理论上,上诉方法支持5.0版本,没测试过4.x版本,有需要的可以按照教程测试一下。
虽然经过一番周折,终于使得平台支持了lambda语法,但是,还是希望公司能尽快更新平台相关技术,支持java的更多新特性。
附上一篇文章地址:
http://bbs.hearker.com/read.php?tid=2534&fid=15

最新喜欢:

杜瑞龙杜瑞龙
刘海龙
侠客
侠客
  • UID366
  • 粉丝0
  • 关注0
  • 发帖数4
沙发#
发布于:2020-11-12 06:26
赞赞赞
游客

返回顶部