spring3.*和jdk8版本冲突问题及解决方案

您所在的位置:网站首页 怎么升级spring版本 spring3.*和jdk8版本冲突问题及解决方案

spring3.*和jdk8版本冲突问题及解决方案

#spring3.*和jdk8版本冲突问题及解决方案| 来源: 网络整理| 查看: 265

背景描述

15年的一个老系统,使用的ssh框架,在1.6jdk下运行了五年,最近因部署环境切换,新环境对JDK版本统一升级为1.8版本,在1.8版本jdk下,系统启动报错。

(整个问题排查过程由新环境平台厂商大牛整理,并征求同意后发出来。)

问题概述

先说结论和解决方案:

问题描述:spring3.* 版本不支持JDK8,启动时报错。

问题原因:spring使用asm类库操作Java class文件,spring3.* 依赖的asm类库版本比较老,而JDK8之后Java class格式有变化,老版本的asm类库不能支持导致报错。

解决方式和建议:

升级spring到spring4以上版本(新应用或老应用大改推荐)

spring4开始正式支持JDK8,实际是升级了配套的asm类库到可以支持JDK8的版本

适用于新应用(新应用也强烈不建议使用spring3版本)

对于老应用从spring3升级到spring4/5可能会引发很多兼容性的问题,最好是整个spring生态一起升级到新版本,但这样工作量会比较大,因此只适合老应用大改。

升级spring到spring3.2.18版本(老应用小改推荐):

Spring3.2.18版本是spring3系列最后一个版本

保持了spring3的兼容性,同时asm类库也升级到了可以支持JDK8的版本

可以比较好的平衡:改动量小,能解决spring3和jdk8的冲突问题,又不必让老应用面临升级spring4大版本的风险

降级JDK到7(老应用完全改不了的最后方案)

不建议采用,JDK7过于陈旧,而且会导致后续没法使用JDK8的特性和支持这些特性的类库

偏离主流技术栈(统一使用JDK8),增加开发运维的复杂度

建议:只有在上面两个方法都无法使用时,不得已而为之的最后备选方案

问题排查

如果对这个问题的细节有兴趣,请细看下面的内容。

问题原始错误信息和输入

JDK 8和spring 3.x不匹配,应用在启动时初始化spring时报错,实际异常如下:

 

 

问题分析

从异常信息看,是spring在启动初始化时,通过 spring-asm 类库操作Java class文件时报错:

Caused by: java.lang.IllegalArgumentException at org.springframework.asm.ClassReader.(Unknown Source) at org.springframework.asm.ClassReader.(Unknown Source) at org.springframework.asm.ClassReader.(Unknown Source) at org.springframework.core.type.classreading.SimpleMetadataReader.(SimpleMetadataReader.java:52) at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:80) at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:101) at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:257) ... 47 more

Spring官方对这个问题的分析:

IllegalArgumentException initializing an application compiled with Java 8:

社区2013年就报告了这个版本冲突问题,从分析上看是spring使用的 asm 类库版本太低,而JDK8之后Java class格式有变化,老版本的asm类库不能支持处理 Jdk8 的class文件导致报错抛异常。

ASM类库介绍

特别高亮一下 ASM 类库,ASM 是Java社区广泛使用的Java字节码操作和分析框架工具,可以用来修改已有的java class文件或者动态生成java class。

ASM官方网站:https://asm.ow2.io/

ASM的版本列表:https://asm.ow2.io/versions.html

ASM对java 8的支持,始于 2013年10月发布的 asm 5.0 bata 版本:

因此,要解决和JDK8的版本冲突问题,就必须升级spring配套的asm类库到asm5.0版本。

Spring使用ASM类库的方式

Spring重度依赖ASM,但spring使用ASM类库的方式比较特殊,历史上有三次变更:

直接使用官方ASM(spring1和spring2):

这是普通使用jar包依赖的方式,在spring 的maven依赖中引入asm,以spring 2 最后一个版本 spring 2.5.6为例:

asm asm 2.2.3 true asm asm-commons 2.2.3 true asm asm-util 2.2.3 true

注意 asm.jar 中的 java package 名是 org.objectweb.asm:

spring-asm(spring3.0和spring3.1版本)

Spring3之后没有再按照普通的方式使用asm官方类库,而是做了一次 repackge,将asm的java package 从 org.objectweb.asm 改名为 org.springframework.asm,然后打包并发布为单独的 spring-asm 类库如 spring-asm-3.0.5.RELEASE.jar

对比如下图:

在这里可以看到 spring-asm 类库的历史版本记录,从3.0.0版本开始,到3.1.4版本结束:

https://repo.spring.io/release/org/springframework/spring-asm/

asm in spring-core(spring3.2及之后的版本)

在spring3.2版本之后,spring修改了repackage asm的方式,package名维持不变,但是不再使用 spring-asm 这样的单独类库,而是把 asm 的内容打包到了 spring-core 中:

spring3.2系列早期版本repackage 的是 asm 4.0 版本,依然不支持jdk8;但在后期版本(应该是从3.2.14或者3.2.16)开始就repackage了支持 asm 5.0版本。

从 spring 的 java docs 文档中可以看到:

https://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/asm/package-summary.html

Spring's repackaging of org.objectweb.asm 5.0 (for internal use only).

简单和安全起见,升级到3.2最后一个版本 3.2.18 是可以确认支持jdk8。

问题验证

出现问题的应用,使用的spring版本是 spring 3.0.5 ,配套的spring-asm 3.0.5 对应的asm是3.0版本,不支持jdk8,因此报错。

验证了以下几种解决方案:

降级JDK到7版本,验证通过:使用了Orcale JDK7U80版本,这是JDK7最后一个小版本

升级spring到3.2.18版本,验证通过

参考资料

IllegalArgumentException initializing an application compiled with Java 8: 社区2013年就报告了这个版本冲突问题,从分析上看是spring使用的 asm 类库版本太低,处理 jdk8 的class文件时报错抛异常。

spring 4 升级踩雷指南: 从描述上看升级spring版本到4而其他依赖的版本不变的话,很大可能性会遇到其他版本兼容问题

Spring context initialization failed with java.lang.IllegalArgumentException while deploying to Apache 7.0.54 and java 8: stackoverflow 上的这个问题,给出了除了升级到spring4之外的另外一个解决方案,即升级到 spring 3.2.16 及以上版本

Spring历史版本列表: 可以看到 spring 3.2.18 是spring3.系列最后一个版本,建议升级 `spring3.` (在不升级到spring4/5的前提下)都升级到这个 spring 3.2.18

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3