写点什么

spring2.5.6+java6 升级到 spring4+java8 了

用户头像
阿水
关注
发布于: 2020 年 12 月 12 日

背景


有些产品开发时间较早,使用的技术栈还是 spring2.5.6+java6。这个技术栈存在几个问题


  • java8 相对 java6 做了很多性能优化,这些年陆陆续续遇到一些 java6 相关的性能问题,比如 java 的 ClassLoader 用的是方法级的synchonized,而 java7 就已经在ClassLoader中提供了一类一锁。

  • java8 的语法相对 java6 来说更便捷,生产效率更高。

  • 国外主流开源项目很多都只提供 java8 以上的 SDK,一旦出现非升级不可的情况,将是灾难性后果。像今年出现的多次fastjson的安全漏洞,如果不是温少照顾中国国情,也只提供 java8 的 sdk,很多项目组将会付出惨痛代价


目前成研负责的数字法院系统(以下简称NP)是全国最多法院在用的核心办案系统,为了让团队成员效率更高,法官们用的更爽,同时避免后续出现无法升级开源项目 SDK 的窘境,NP 将尝试将 spring 和 java 进行升级。


升级方案


基于 spring2.5.6 源码进行改造


网上提到的方案都是定制一下 spring 的JDKVersion这个类,用这种方案只是说你的程序能在jdk8运行起来,但是无法用到java8的新语法,因为 spring2.5.6 是不支持lambda表达式的,spring 在启动时会报错。 



也有人给spring官方提了相应问题,希望 spring 官方能让 spring2.5.6 支持 java8,官方的答复是哪凉快哪呆着去。既然官方不干,那我可以试着代官方行事,修改一个支持 java8 的 spring2.5.6 版本。


结合上述报错信息,我就把org.springframework.asm的代码拿出来进行修改,但是经过两个小时的努力,发现这个工作量不小。先舍弃这种方案。


直接将 spring2.5.6 升级到 spring4.XX


spring4.XX 是官方支持 java8 的最小版本。跨两个大版本升级,心里还是有些没底的。但是经过三个小时的努力,终于成功的将 NP 升级到spring4.2.3。在升级过程中,陆续出现了十多个错误,但基本上没有改代码,只是各种升级 jar 包和修改配置。以下是升级中出现的错误和相应的解决方案。


bouncycastle 循环依赖


Caused by: java.lang.IllegalStateException: Unable to complete the scan for annotations for web application [/spxt] due to a StackOverflowError. Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies.The class hierarchy being processed was [org.bouncycastle.asn1.ASN1EncodableVector->org.bouncycastle.asn1.DEREncodableVector->org.bouncycastle.asn1.ASN1EncodableVector]
复制代码


这个是bcprov出现了 jar 包冲突,只是以前 spring2.5.6 的时候没报错,spring4.XX 更加严格了。删除重复的 jar 包,我只保留了bcprov-jdk16-1.46,也可以考虑升级到更新的版本


各种 ClassNotFoundException


Caused by: java.lang.ClassNotFoundException: org.springframework.scheduling.quartz.JobDetailBean


这个类改名了,改成JobDetailFactoryBean


ClassNotFoundException: org.springframework.scheduling.quartz.CronTriggerBean 这个类改名了,改成CronTriggerFactoryBean


NoClassDefFoundError: org/apache/neethi/PolicyBuilder


升级 neethi 到 3.1.1.jar


Requested bean is currently in creation: Is there an unresolvable circular reference?


spring 的 bean 出现了循环依赖,以前有循环依赖的话,spring2.5.6 会想办法兼容解决,但是其实也遗留了很多隐患,NP 深受其害。个中原由略去不讲,大家在程序设计时,要好好设计,不要出现 bean 的循环依赖。


如果不重构代码的话,可以在 bean 的申明时加一个 @Lazy 的注解,这样 A 依赖 B,B 依赖 A 的话,把 B 这个 bean 设为懒加载。


ClassFormatException Invalid byte tag in constant pool: 18


Caused by: org.aspectj.apache.bcel.classfile.ClassFormatException: File: 'com.thunisoft.XXXService': Invalid byte tag in constant pool: 18	at org.aspectj.apache.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:192)	at org.aspectj.apache.bcel.classfile.ClassParser.parse(ClassParser.java:131)	at org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository.loadJavaClass(NonCachingClassLoaderRepository.java:262)	at org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository.loadClass(NonCachingClassLoaderRepository.java:242)	at org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository.loadClass(NonCachingClassLoaderRepository.java:249)
复制代码


升级 aspectJ 到1.8解决


hibernate 相关问题


hibernate 升级到3.6.10.FINAL,这个版本相对项目中用到的 3.2.6 改动很小,如果升级到 hibernate4 或者 5 的话,改动量会很大。升级 hibernate 时遇到了一些小问题,比如项目中重写了LocalSessionFactoryBeanconfigurationClass,hibernate3.6.10 改了这个类,所以如果用到了的话需要改一行代码。


Caused by: java.sql.SQLException: Incorrect syntax near 'cross'.


我们用的是 sybase 数据库,改一下 hibernate 方言,用SybaseASE157Dialect这个方言。


cxf 升级


项目中用到了 cxf2.XX,和 spring4 不兼容,统一升级到 cxf3.0.1 版本解决。中间也遇到了一些小的配置问题。比如<import resource="classpath:META-INF/ cxf/ cxf-extension-soap.xml" />这个配置要删掉,高版本没有这个文件了。


还有Caused by: java.lang.NoSuchFieldError: QUALIFIED,这个是升级xmlschema-core到2.1.0.jar


然后项目就跑起来啦,当他跑


后记


还有一些项目特有的问题就不一一描述了,每次遇到一个错就解决一个错,再重启验证,就这么来回十几次,当我最后一次发现控制台没有错误信息的时候,这种喜悦只有写代码的人才能感受到。我小心翼翼的打开浏览器,输入网址,运行,页面加载的那三秒钟是今年最长的三秒钟,但是一切还好,老天没有耍我。


十年前我刚入职时,按照架构师写的文档把项目框架搭建起来,十年过去了,我又来改 NP 代码了。本来这事轮不到我的,找了好几个人,都说不好升级,工作量大。以后大家要慎重点哦。


发布于: 2020 年 12 月 12 日阅读数: 37
用户头像

阿水

关注

道阻且长,行则将至。 2017.11.28 加入

北京华宇信息技术有限公司成都研发中心技术副总,从业11年的码农。

评论

发布
暂无评论
spring2.5.6+java6升级到spring4+java8了