EMT4J详细介绍与使用,帮你找到Java版本升级带来的问题,让你在项目jdk升级不在头疼
- IT业界
- 2025-08-20 10:06:01

Java版本升级带来的问题 前因
java更新迭代速度巨快无比,Spring Framework 6 等项目已经至少需要 Java 17。但是,对于 Java 版本的采用是相对缓慢的。例如,在 Java 11 发布四年之后(2022年),只有不到 49%的 Java 应用在使用11版本。
但是:例如Spring Framework 出现了性能极高的优化,甚至其他框架也出现了里程碑式优化,那面就升级Java版本带来的优势是大于弊端的
后果将应用升级至新的 Java 版本,意味着开发人员需要解决 Java 内部变更和功能移除所带来的所有问题。这涉及的功能包括 Nashorn、J2EE 和 Java 等包的移除、API 的变更以及对 Java 内部访问更严格的限制。盲目的升级至新的版本,很有可能造成应用中断等不可控因素。
问道包括但不局限于:
1、删除了一些 API 如 sun.misc.*导致代码出现 ClassNotFoundException。
2、Java Version 的 Schema 发生变化导致原来判断 Java 版本的逻辑出现异常。
3、用户代码中使用了私有的 API,使用了标记为废弃的 API 等。
4、JPMS(Java Platform Module System)的引入导致一些反射代码会无法工作。
5、删除了 J2EE 相关的包。
如果需要升级的应用依赖了成百上千的二方和三方 jar,而这些 jar 可能也存在兼容性问题,更进一步,如果需要升级的应用几十个甚至几百个,那么带来的额外工作量可想而知。
版本升级问题案例Java8 -> Java11 升级中API的变化如下
DK 11中删除的各个API类/方法被删除附加说明/参考java.lang.Runtime.runFinalizersOnExit(boolean)危险运行FinalizersOnExit 弃用Java的终结器java.lang.SecurityManager.checkAwtEventQueueAccess()安全管理器和Java SE JDK JDK-8177554 JDK-8029886 JDK-8186535java.lang.SecurityManager.checkMemberAccess(java.lang.Class,int)java.lang.SecurityManager.checkSystemClipboardAccess()java.lang.SecurityManager.checkTopLevelWindow(java.lang.Object)java.lang.System.runFinalizersOnExit(boolean)危险运行FinalizersOnExit 弃用Java的终结器java.lang.Thread.destroy()线程方法destroy()和stop(Throwable)在JDK 11中删除java.lang.Thread.stop(java.lang.Throwable) 从Java 11中删除模块级API名称模块已卸下潜在的第三方更换JavaBeans激活框架 (JAF)java.activationMaven神器通用对象请求代理体系结构 (CORBA)java.corba玻璃鱼-科尔巴下表中列出的其他模块的聚合器模块java.se.eeJava交易API (JTA)java.transactionMaven神器XML绑定的Java体系结构 ( JAXB )java.xml.bindMaven神器XML Web Services的Java API (JAX-WS)java.xml.wsMaven神器常用注释java.xml.ws.annotationMaven神器以 java.lang.Thread.stop(java.lang.Throwable) API 为例,演示版本升级带来危害。
简单的SpringBoot项目
@RestController @RequestMapping("/test") public class TestController { @GetMapping("/testemt") public String testEmt(){ Thread thread = new Thread(); try{ thread.stop(new Exception()); } catch (UnsupportedOperationException e){ System.out.println( "捕获UnsupportedOperationException " + e); return "error !"; } return "success !"; } } Java8在jdk 1.8版本中 ,项目会正常运行没有问题,同时可以捕获异常
升级到Java11如果升级到 jdk 11 版本 ,首相项目就会报错,因为 11 版本已经没有java.lang.Thread.stop(java.lang.Throwable)这个方法了。
再次访问方法的既定URL 会报错,应用产生中断报错
后台日志会打印没有 java.lang.Thread.stop(java.lang.Throwable)方法的error日志
版本升级应对方案EMT4J 目前支持了从 JDK 8 升级到 JDK 11&17 的分析,后续也会不断的更新对于最新的 LTS 版本的支持。
目前支持通过如下 3 种方式使用:
Maven插件 可以在开发阶段就发现问题命令行工具 无需启动应用,但可能存在误报Java Agent 可以获取项目运行时上下文,获取调用栈,报表信息更准确EMT4J 官网中详细记录三种使用方案
EMT4J: github /adoptium/emt4j#use-the-emt4j-agent
下面仅列出Maven插件使用方法
将以下配置添加到 pom.xml(如果是多模块项目.xml根 pom):
<build> <plugins> <plugin> <groupId>org.eclipse.emt4j</groupId> <artifactId>emt4j-maven-plugin</artifactId> <version>0.7.0</version> <executions> <execution> <phase>process-test-classes</phase> <goals> <goal>check</goal> </goals> </execution> </executions> <configuration> <fromVersion>8</fromVersion> <toVersion>11</toVersion> <outputFile>report.html</outputFile> </configuration> </plugin> </plugins> </build>然后运行以下命令:
$ mvn process-test-classesEMT4J的报告将在项目目录中生成。
用户也可以直接运行以下命令,无需修改pom.xml:
# 通过默认配置运行
$ mvn process-test-classes org.eclipse.emt4j:emt4j-maven-plugin:0.7.0:check# 通过 -D 指定文件来执行
$ mvn process-test-classes org.eclipse.emt4j:emt4j-maven-plugin:0.7.0:check -D outputFile=emt4j-report.html -D priority=p1配置:
fromVersion:项目当前使用的 JDK 版本。支持 8 和 11,默认支持 8。toVersion:目标 JDK 版本。支持 11 和 17,默认为 11。outputFile:EMT4J报告的目的地。默认值为报表.html。priority:最低规则优先级。支持 P1、P2、P3 和 P4。未设置默认值。verbose:如果为 true,则打印更详细的消息。EMT4J详细介绍与使用,帮你找到Java版本升级带来的问题,让你在项目jdk升级不在头疼由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“EMT4J详细介绍与使用,帮你找到Java版本升级带来的问题,让你在项目jdk升级不在头疼”
上一篇
Python爬虫以及数据可视化分析之某站热搜排行榜信息爬取分
下一篇
关于栈和队列