EMT4J——让 Java 应用升级更轻松

JDK 升级对于 Java 应用来说是不得不面对的事情,一方面 Java 生态系统希望 Java 应用能跟上最新 JDK 版本:

  • Oracle 建议将 JDK 的 LTS 版本的发布周期从 3 年调整为 2 年,对于只使用 LTS 版本的应用来说,可以在更短时间内使用最新的技术,但这也意味着版本升级会更加频繁。
  • Spring Framework 6 只支持 JDK 17。Spring 是大多数企业级应用依赖的基础框架,意味着不得不升级到 JDK 17。

但是另一方面,现实中的 Java 应用的 JDK 升级较为缓慢。JDK 11 从 2018 年发布近 4 年,已升级 JDK 11 仍未达到半数(2022-state-of-java-ecosystem)。而相比之下,JDK 8 发布之后 1 年内可达到 38%,两年达到 64.3%,到 2018 年时近 80%(java-8-adoption-march-2016、jvm-ecosystem-report-2018)。

那为什么升级 JDK 11 积极性不高呢?

可能的原因是多方面的。例如 JDK 8 在语言层面引入了 Lambda 对开发人员非常有吸引力,而 JDK 11 在语言层面的更新显得可有可无。但是有一点是非常明显的,相比从其它版本升级到 JDK 8(JDK 6/7 升级到 JDK 8 对于应用基本无感),升级到 JDK 11/17 难度会大很多,可能会遇到很多兼容性问题,如:

1、删除了一些 API 如 sun.misc.*导致代码出现 ClassNotFoundException。

2、Java Version 的 Schema 发生变化导致原来判断 Java 版本的逻辑出现异常。

3、用户代码中使用了私有的 API,使用了标记为废弃的 API 等。

4、JPMS(Java Platform Module System)的引入导致一些反射代码会无法工作。

5、删除了 J2EE 相关的包。

如果需要升级的应用依赖了成百上千的二方和三方 jar,而这些 jar 可能也存在兼容性问题,更进一步,如果需要升级的应用几十个甚至几百个,那么带来的额外工作量可想而知。

正是由于上述的困难,阿里巴巴内部将这些升级的经验通过工具沉淀下来,希望能够通过工具帮忙更多的 Java 应用更高效的升级最新版本 JDK。

目前 Eclipse Migration Toolkit for Java(简称”EMT4J”)已经在 Eclipse 社区开源,并通过了 Eclipse Adoptium PMC 评审,作为 Eclipse Adoptium 子项目进行孵化。阿里云也是 Eclipse Adoptium 工作组的战略基石成员,参与 Eclipse Adoptium 社区治理,为 Java Ecosystem 提供完全兼容的、基于 OpenJDK 的高质量 JDK 发行版。

EMT4J 目前支持了从 JDK 8 升级到 JDK 11&17 的分析,后续也会不断的更新对于最新的 LTS 版本的支持。

目前支持通过如下 3 种方式使用:

  • Java Agent
  • 命令行工具
  • Maven插件

EMT4J 架构图如下:

以一个常见的场景来说明工具的使用:

开发人员张三接到任务,需要将所在团队负责的 8 个 Java 应用(app-service-1 到app-service-8)从 JDK 8 升级到 JDK 17,那张三在 EMT4J 的帮助下如何升级呢?

具体升级操作我们分以下七步走:
1、张三下载了 EMT4J 工具到本地,并且在 /home/jdk17 本地安装了目标版本的 JDK 17。

2、将 app-service-1~app-service-8 的应用包下载到 EMT4J 所在机器,放在目录 /home/app/deploy,并将 app-service-1~app-service-8 的 JVM 选项放入到 .cfg 的文本文件,放在目录 /home/app/vmoptions。

3、运行工具检查: sh ${EMT4J_HOME}/bin/analysis.sh -f 8 -t 17 -j /home/jdk17 /home/app,其中 -f 8 -t 17 表示从 8 升级到 17, -j /home/jdk17_表示目标版本 JDK 的安装目录, /home/app_表示需要检查的应用包以及参数文件。命令执行完成以后,默认会在当前目录生成 report.html。打开检查报告report.html 查看到问题的列表如下:

5、张三打开 app-service-1 的工程看到如下的代码,下面的代码显然是无法处理类似于 17.0.1 版本号。

6、张三参考报告中的 How to fix 了解到 JDK 9 以后 Java Version 的 Schema 发生了变化,按新的 Schema 修改代码。

7、张三按依次参考报告中对其它问题修改。修改完成以后,在开发机器上使用目标版本 JDK 启动验证功能正确性。

以上使用 EMT4J 工具帮助张三从 JDK 8 成功地升级到 JDK 17,那么 EMT4J 工具具有哪些特性?

1、支持 Java Agent、命令行工具以及 Maven 插件等方式使用

  • Java Agent 可以获取更多运行时上下文信息,能提供准确调用栈,能发现更多的问题
  • 命令行工具方便使用,无须启动应用,但是可能会存在误报
  • Maven 插件可以集成在构建阶段,可在开发阶段发现问题

2、支持多种潜在不兼容性问题分析

  • JDK 8 到 JDK 11

  • JDK Internal API 的使用

  • System ClassLoader 不再是 URLClassLoader 子类
  • Arrays.asList 返回类型变化
  • Java Version 的 Shema 发生变更
  • JPMS 需要增加 add-exports 和 add-opens
  • 时区数据变更为 CLDR 引起相关不兼容
  • Pattern.compile 的 API 变更
  • JVM 选项变更
  • JDK 11 到 JDK 17

  • 删除了 Nashorn

  • 删除了RMI 和 Java Applet
  • 部分 Class 无法反射获取 Field

3、支持 HTML、TXT 和 JSON 格式的输出

如果您在使用 EMT4J 的过程中,遇到如下的问题:

  • 工具应该发现的兼容性问题,但是实际没有发现
  • 工具报告的问题上下文不准确,不方便查找问题在哪里
  • 工具报告的问题描述不清晰,难以指导如何修改增加一些新的功能,比如工具支持其它一些格式

都可以通过如下的方式参与贡献:

  • 创建 issue 描述您遇到的问题
  • 自己 Fork 以后修改测试后,并通过 PR 合入 master

结语:因为目前还有很多的 Java 应用仍然停留在 JDK 8上,所以这些应用正在规划或者正在升级 JDK 中,希望通过 EMT4J 让我们的升级工作更轻松一些。

我们在工具中沉淀了阿里巴巴升级 JDK 的经验,但是肯定还有很多我们没有遇到的兼容性问题,另外 JDK 新的版本不断会发布,也会不断有新的兼容性问题出来。我们希望通过开源的方式,能够有更多的开发者参与到工具中,给工具不断增强功能,让更多的 Java 应用升级变得更简单。更多内容 (如何使用、贡献等) 可以参考:

—— 完 ——

加入龙蜥社群

加入微信群:添加社区助理-龙蜥社区小龙(微信:openanolis_assis),备注【龙蜥】与你同在;加入钉钉群:扫描下方钉钉群二维码。欢迎开发者/用户加入龙蜥社区(OpenAnolis)交流,共同推进龙蜥社区的发展,一起打造一个活跃的、健康的开源操作系统生态!

关于龙蜥社区

龙蜥社区(OpenAnolis)由企事业单位、高等院校、科研单位、非营利性组织、个人等在自愿、平等、开源、协作的基础上组成的非盈利性开源社区。龙蜥社区成立于 2020 年 9 月,旨在构建一个开源、中立、开放的Linux 上游发行版社区及创新平台。

龙蜥社区成立的短期目标是开发龙蜥操作系统(Anolis OS)作为 CentOS 停服后的应对方案,构建一个兼容国际 Linux 主流厂商的社区发行版。中长期目标是探索打造一个面向未来的操作系统,建立统一的开源操作系统生态,孵化创新开源项目,繁荣开源生态。

目前,Anolis OS 8.6 已发布,更多龙蜥自研特性,支持 X86_64 、RISC-V、Arm64、LoongArch 架构,完善适配 Intel、兆芯、鲲鹏、龙芯等芯片,并提供全栈国密支持。

欢迎下载:

加入我们,一起打造面向未来的开源操作系统!

Original: https://www.cnblogs.com/yunqishequ/p/16551478.html
Author: 阿里云云栖号
Title: EMT4J——让 Java 应用升级更轻松

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/537104/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Mysql 5.7开启binlog日志

    Mysql 5.7开启binlog日志 前言 binlog是MySQL的二进制日志,并且是MySQL中最重要的日志。binlog记录了对MySQL数据库执行更改的所有操作,包括对数…

    Java 2023年6月15日
    087
  • springboot使用log4j2代替内置log4j

    前言 log4j是apache实现的一个开源日志组件 logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现 l…

    Java 2023年5月30日
    075
  • Spring Boot入门一:在Eclipse中使用Spring boot

    1.安装插件 打开Eclipse-Help-Eclipse Marketplace-搜索spring tools,找到对应工具安装 下载完成后,重启eclipse,选择新建proj…

    Java 2023年5月30日
    066
  • 1-Java基础

    一、基础常识 软件:及一些列按照特定顺序组织的计算机数据和指令的集合。分为:系统软件和应用软件。系统软件:windows , mac os , linux ,unix,androi…

    Java 2023年6月7日
    077
  • Java调用阿里云OSS下载文件

    1、准备工作 2、项目需求 首先需要引入阿里云的依赖包,如下所示: 如果只是想将oss文件下载到服务器的磁盘里面,可以使用下面的案例。需要注意的就是OSS的文件目录下面的文件,指定…

    Java 2023年5月29日
    081
  • JVM-内存区域与OOM

    本篇博客内容主要参考《深入理解Java虚拟机》 内存区域与内存溢出异常 运行时数据区 Java虚拟机运行时数据区: 程序计数器(Program Counter Register)是…

    Java 2023年6月7日
    0100
  • nginx 替换

    nginx: [emerg] the “ssl” parameter requires ngx_http_ssl_module in /usr/local/…

    Java 2023年5月30日
    072
  • Java学习——数组的基础知识

    二维数组的声明和初始化 静态初始化: int[][] arr1 = new int[][]{{1,2,3},{6,8},{3,6,8,9}}; 动态初始化: ​ ① String[…

    Java 2023年6月5日
    068
  • Win10 系统中修改电脑 系统user 名称

    以下步骤来自于:南京邮电大学 ,22级,继教院,通信工程专业,王骏 同学的分享 1.win+R 输入regedit 回车,进入注册表。 2.定位到HKEY_LOCAL_MACHIN…

    Java 2023年6月14日
    079
  • Quartz高可用定时任务快速上手

    如果你想做定时任务,有 高可用方面的需求,或者仅仅想 入门&#…

    Java 2023年6月6日
    075
  • 人工智能与机器学习的不同之处

    人工智能早已不是一个新名词,它的发展历史已经有几十年。从80年代早期开始,当时计算机科学家设计出可以学习和模仿人类行为的算法。在学习方面,最重要的算法是神经网络,但由于模型过于强大…

    Java 2023年6月5日
    075
  • 力扣算法题9. 回文数(Java)

    力扣算法题9. 回文数(Java) 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一…

    Java 2023年6月7日
    074
  • 隔离这几天开发了一个带控制台的OAuth2授权服务器分享给大家

    停更这些天,业余时间和粉丝群的几个大佬合作写了一个基于 Spring Authorization Server的 OAuth2授权服务器的管理控制台项目Id Server,我觉得这…

    Java 2023年6月8日
    064
  • 基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(TableGo v7.0.0版)

    TableGo_20210212 v7.0.0 正式版发布,此次版本更新如下:1、新增对DB2数据库的支持2、新增按字段生成文件,支持把字段、JSON、XML数据转换成任何代码3、…

    Java 2023年6月9日
    072
  • 一个较重的代码坏味:“炫技式”的单行代码

    风格和习惯很重要。 很多代码坏味都是由于不良的风格和习惯导致的,并不涉及高深复杂的技术。 有一些众所周知的代码坏味。当然,也有一些个人觉得很不好的习惯和做法。我个人就不喜欢把多行代…

    Java 2023年6月9日
    062
  • java 的多态 学习理解

    Father a = new Son(); 子类的实例引用 可以 无障碍 赋给 超类的对象变量; 可调用的方法: 以对象变量a 为例, a 能调用的方法 主要看 左边 的类型 里有…

    Java 2023年6月13日
    076
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球