在采用新版本 Java 之前必须考虑的一些注意事项/风险

被新版本系列”绑架”

如果采用了 Java 12 并使用新的语言特性或新的 API,这意味着实际上你已将项目绑定到 Java 的新版本系列。接下来你必须采用 Java 13, 14, 15, 16 和 17。

使用了新版本,每个版本的使用寿命为六个月,并且在发布后仅七个月就过时了。这是因为每个版本只有在六个月内提供安全补丁,发布后1个月的第一个补丁和发布后4个月的第二个补丁。7个月后,下一组安全补丁会发布,但旧版本不能获取更新。

因此,你要判断自身的开发流程是否允许升级 Java 版本,一个月的时间窗口方面会不会太狭窄?或者你是否愿意在安全基线以下的Java版本上运行?

升级的”绊脚石”

实际使用中有很多阻止我们升级 Java 的因素,下面列出一些常见的:

  • 开发资源不足:你的团队可能会非常忙碌或规模太小,你能保证两年后从 Java 15 升级到 16 的开发时间吗?
  • 构建工具和 IDE:使用的 IDE 是否会在发布当天支持每个新版本?Maven? Gradle 呢? 如果不是,你有后备计划吗?请记住,你只有1个月的时间来完成升级、测试并将其发布到生产环境中。此外还包括 Checkstyle,JaCoCo,PMD,SpotBugs 等等其他工具。
  • 依赖关系:你的依赖关系是否都准备好用于每个新版本?请记住,它不仅仅是直接依赖项,而是技术堆栈中的所有内容。字节码操作库尤其受到影响,例如 ByteBuddy 和 ASM。
  • 框架:这是另一种依赖,但是一个大而重要的依赖。在一个月的狭窄时间窗口内,Spring 会每六个月发布一个新版本吗? Jakarta EE(以前的 Java EE)会吗?如果它们不这样做会怎么样?

现在,任何阻挡者的传统方法都是等待:在开始升级之前等待6到12个月,以便为工具,库和框架提供修复任何错误的机会。

云 / 托管 / 部署

你是否可以控制代码在生产环境中的运行位置和方式?例如,如果你在 AWS(Amazon Web Service) Lambda 中运行代码,则无法控制。AWS Lambda 没有采用 Java 9或10,甚至没有采用 Java 11。所以除非 AWS 提供公共保证以支持每个新的 Java 版本,否则根本无法采用 Java 12。(我的工作假设是AWS Lambda仅支持主要的LTS版本,由Amazon Corretto JDK公告支持。)
如何托管你的 CI 系统?Jenkins, Travis, Circle, Shippable, GitLab 会快速更新吗?如果不是,你会怎么做?

为采用新版本进行规划

如果正在考虑采用新版本的 Java,建议你准备一份现在所依赖的所有内容的清单,或者可能在未来3年内会依赖的。你需要保证该列表中的所有内容都能正常工作,并与新版本一起升级,或者如果该依赖项不再更新,请制定好计划。以某位互联网开发者为例,他列的清单如下:
image.png
说了这么多,当然不是鼓励大家不进行升级,新语言特性带来的好处以及性能增强会让开发者受益,但升级背后的风险也应该考虑进去

其他第三方的厂商声明

Spring 框架已经在视频中表达了对 Java 12 的策略。关键部分是:
image.png
作为典型软件供应商的一个例子,Liferay 声明如下:
image.png
个人的想法:
image.png

再谈JDK版本更新

image.png

  • 在 Java 9 之前,当一个版本被宣布为首选版本,存在一个“培育”(bedded-in)新 GA 版本的重叠期。在此期间,上一个版本将会继续进行免费更新。为确保新旧版本间的干净切换,即便旧版本已不再是首选版本,通常也会继续维护12 个月以上。但是随着 Java 版本发布更改为遵循严格的时间表后,事实上宣告了传统的免费支持期将寿终正寝。
  • 也许不会有太多公司直接选择 JDK12、JDK 13,但个别的生产实践并不遥远。比如,实际工作场景中,利用 JDK 12的 Abortable Mixed Collections for G1,解决了 HDFS 在特定场景中 G1 Evacuation 时间过长的困扰,虽然最后团队选择将其 backport 到了自己的 JDK11 版本中,但如果没有快速交付的预览版 JDK12,也不会如此快速的得到结论。
  • 而对另一个问题,目前看是非常成功的,解开了 Java/JVM 演进的许多枷锁,至关重要的是,OpenJDK 的权力中心,正在转移到开发社区和开发者手中。在新的模式中,既可以利用 LTS 满足企业长期可靠支持的需求,也可以满足各种开发者对于新特性迭代的诉求。你可能注意到了 Switch Expressions 被打上了预览(Preview)的标签,Shenandoah GC 则是实验(Experimental)特性,这些都是以往的发布周期下不大现实的,因为用 2-3 年的最小间隔粒度来实验一个特性,基本是不现实的。
  • 可以预计,JDK8 在未来的一段时间仍将是主流,我们已经注意到 Amazon、Alibaba、Redhat、AdoptOpenJDK 等等厂商或社区,纷纷发布了自己的 JDK8 等产品,开始竞赛长期支持版本 JDK 的主导权,这是非常好的迹象,反映了主流厂商对于 Java 的投资力度增大
  • 是否会带来 Java/JVM 的碎片化呢?多少会发生一些,但从目前的合作模式来看,OpenJDK 仍然是合作的中心,主导这 Java 历史版本维护和未来的演进路线。

    Oracle撒手, OpenJDK继续向前

  • Java 8 是目前使用率最高的一个 Java 版本,发布于 2014 年,而 Oracle 对 Java 8 的官方支持时间持续到 2020 年 12月,之后将不再为个人桌面用户提供 Oracle JDK 8 的修复更新;在 2019 年 1 月之后,不再提供免费的商业版本更新,届时想要继续获得 Oracle 的商业支持和维护,需付费订阅。

  • 近日,Oracle 的销售代表发出的一封邮件引起了热议,该邮件称“Java 8 的非公开可用的关键补丁更新”将于 2019年 4 月 16 日发布,拥有有效许可证的客户才可以享用。邮件继续称,如果没有安装这些更新,可能导致“你的服务器和桌面环境暴露且易受攻击。”
  • 但在许多 Java 用户看来,这封邮件像是一种敲诈勒索或恐吓策略

image.png

  • 虽然 Oracle 官方选择了不再支持,但 Java 社区却把担子接了下来。红帽 Java 平台团队的首席工程师 AndrewHaley 曾表示,红帽计划在 2023 年之前继续提供对 OpenJDK 8 的支持:
  • “在我看来,这算比较正常的。几年前,OpenJDK 6 更新(jdk6u)项目被 Oracle 放弃,我接管了它,然后OpenJDK 7 也发生了同样的事情。最后,Azul 的 Andrew Brygin 接管了 OpenJDK 6。由来自多个组织成员组成的OpenJDK Vulnerability Group 就重要的安全问题进行协作。在广大的 OpenJDK 社区和我的团队(Red Hat)的帮助下,我们定期为关键 bug 和安全漏洞提供更新。我觉得这样的过程同样适用于 OpenJDK 8 和下一个长期支持版本,即 OpenJDK 11。
  • 如果可以得到社区的支持,我很高兴能够领导 JDK 8 更新项目和 JDK 11 更新项目。”
  • 除了红帽以外,AWS 推出了 OpenJDK 长期支持版本 Amazon Corretto。阿里巴巴也开源了 OpenJDK 长期支持版本Alibaba Dragonwell

    未来展望

  • Java 的变化速度从未如此之快——如今,该语言的新版本每六个月就会发布一次

  • 而之所以能够实现如此重大的转变,自然离不开一系列专注于提高其性能添加新功能的协作性项目的贡献。这些项目的目标可谓雄心勃勃。正如 JetBrains 开发者布道师 Trisha Gee 在 QCon 伦敦 2019 大会上所言,“Java 即将迎来很多超酷的东西。”
  • 而发展道路中的以下三大主要项目,将有助于确定 Java 的未来方向

    项目一:Loom项目

  • 尝试改进 Java 语言的并发处理方式,或者说是在对计算机在不同指令集执行之间切换能力的探索

  • 甲骨文公司 Loom 项目技术负责人 Ron Pressler 在 QCon 伦敦 2019 大会上向希望编写软件以处理并发任务的 Java开发者们提出了两种都不够完美的选项:要么编写无法通过扩展处理大量并发任务的“简单同步阻塞代码”,要么编写可扩展但编写难度极高且调试过程复杂的异步代码。
  • 为了寻求解决这个问题的方法,Loom 项目引入了一种将任务拆分为线程的新方法——所谓线程,即是指计算机在运行指令时的最小可能执行单元。在这方面,Loom 引入了被称为 fibers 的新型轻量级用户线程。
  • 他在大会上指出,“利用 fibers,如果我们确保其轻量化程度高于内核提供的线程,那么问题就得到了解决。大家将能够尽可能多地使用这些用户模式下的轻量级线程,且基本不会出现任何阻塞问题。”
  • 利用这些新的 fibers,用户将能够扩展 Java 虚拟机(JVM)以支持定界延续(delimited continuations)机制,从而使得指令集的执行实现暂停以及恢复。对这些延续进行暂停与恢复的任务将由 Java 中的 ForkJoinPool 调度程序以异步模式处理
  • 根据说明文档所言,fibers 将使用与 Java 现有 Thread 类非常相似的 API,这意味着 Java 开发人员的学习曲线应该不会太过陡峭。

    项目二:Amber项目

  • Amber 项目的目标,在于支持“更小、面向生产力的 Java 语言功能”的开发,从而加快将新功能添加至 Java 语言中的速度。

  • 这套方案非常适合自 Java 9 以来,以更快速度持续发布的各 Java 新版本。
  • 目前,以下 JDK 增强提案(简称 JEP)正在进行当中,并隶属于 Amber 项目之内。
  • 生成字符串
  • 生字符串使得开发人员能够更轻松地对文本进行适当格式化,且无需引入由转义字符带来的复杂性。
  • 举例来说,开发人员不必使用转义字符来表示换行符,因此在以下字符串中:

image.png
该提案的说明文档中提到,这一变更将使得各类文本客串的输入变得更加简单,包括文件路径以及 SQL 语句等等。
如大家所见,生字符串应被包含在反引号之内。
用于 JDK API 的 Java 编译器 Intrinsic:

https://openjdk.java.net/jeps/348

此项提案将允许开发人员对需要定期调用的重要代码段进行性能优化。

Pattern Matching 能够简化利用 Java 中 instanceof 运算符检查对象是否属于特定类的过程,而后提取该对象的组件以进行进一步处理。如此一来,以下操作语法:
image.png

Switch expressions 已经在 Java 12 当中以预览版形式推出,允许开发人员利用更简单的语法通过 switch 语句为输入内容指定不同的响应方式。举例来说,现在我们不再需要始终在以下语法当中使用 switch 语句:image.pngimage.png

项目三:Valhalla项目

Valhalla 项目专注于支持“高级”JVM 与语言功能的开发。
目前 Valhalla 项目的候选提案还比较有限,具体包括:image.png
这些新的不可变类型将拥有与 int 等基元类似的内存效率,但同时又与普通类一样能够保存一整套基元集合。提案说明文档中指出,其目标在于“为 JVM 基础设施提供处理不可变与无引用对象的能力,从而实现使用非基元类型进行高效按值计算的目标。
image.png