搭上火箭也追不上的 Java 更新速度,很多程序员们大呼,我可不能够坚持使用 Java 8?!可是对于已使用到 LTS 版本的 Java 11 开发者,是否还有必要往上升级?java
640?wx_fmt=png程序员
本文经受权转自开源中国安全
距离 Java 11 的正式发布已过去一个多月,而 Java 12 也正在赶来的路上。根据此前开源中国发起的一项关于开发者使用的 Java 版本的调查(https://www.oschina.net/quest...)显示,Java 8 仍然是开发者的主流选择,而 Java 11 是 Java 8 以后的首个 LTS 版本,因此有很多开发者表示会选择升级至 Java 11。按照 Java 的发布计划,Java 12 将于明年 3 月推出,那么问题来了,咱们是应该采用 Java 12,仍是坚持使用 Java 11 呢?框架
可能你会以为这是一个可有可无的问题,但对于那些须要在 JVM 中使用 Java 的开发者,或是比较看重 Java 新特性的开发者,这是一项十分重要的决策。这篇文章将和你们就这个问题进行相关的分析。maven
640?wx_fmt=png工具
Java 发布计划性能
如今每六个月就会发布一个新的 Java 版本,因此尽管 Java 11 才发布不久,但距离 Java 12 的发布也就剩下不到五个月的时间。做为发布计划的一部分,某些版本会被指定为长期支持版本(LTS),它们会得到四年或更长时间的技术支持和安全补丁。因此这些版本一般会被称为“主要版本” —— 不是由于它们拥有更多的功能特性,而是由于它们具备长期的技术支持。测试
预计 Java 11 的更新补丁(11.0.1, 11.0.2, 11.0.3 等)将比 Java 8 的补丁(8u20, 8u40, 8u60)更小更简单。由于 Java 11 的更新将更加集中在安全补丁上,不会像 Java 8 的更新那样带来内部的功能加强。由于 Oracle 但愿将 Java 12, 13, 14 等这些版本当作是小更新版本,类比成 Java 8 的话,便是 Java 11u20, 11u40。.net
Oracle 高级员工一再认为像 8u20 和 8u40 这样的更新经常会带来破坏性的变动,但本文做者表示这不是本身的经历,他记得的惟一有破坏性的变化是为 Javadoc 添加了 --allow-script-in-comments,但它也不是 Java 的核心部分。所以,他从不担忧升级到最新版本带来的影响 —— 由于这是 Java 平台的核心优点。插件
下面深刻了解一下为何在旧的发布模式下,升级版本不会致使任何问题。先看一下新旧发布模式之间的差别:
640?wx_fmt=png
640?wx_fmt=png
Oracle 的官方观点认为:与 Java 7->8->9 相比,Java 9->10->11的升级和 8->8u20->8u40 更类似。
表格清楚地显示新模式下的 Java 版本发布都会包含许多变动,包括语言变动和 JVM 变动,这二者都会对 IDE、字节码库和框架产生重大影响。此外,不只会新增其余 API,还会有 API 被删除(这在 Java 8 以前没有发生过)。
Oracle 的观点是,由于每一个版本仅在前一个版本发布后的 6 个月推出,因此不会有太多新的“东西”,所以升级并不困难。虽然如此,但这不是重点。重要的是升级是否有可能会破坏代码。很明显,从 11 -> 12 -> 13 开始,代码遭受破坏的可能性要大于 8 -> 8u20 -> 8u40。
11 -> 12 -> 13 与 8u20 -> 8u40 等这样的更新主要区别在于对字节码版本的更改以及对规范的更改,对字节码版本的更改每每特别具备破坏性,大多数框架都大量使用与每一个字节码版本密切相关的 ASM 或 ByteBuddy 等库。而 8u20 -> 8u40 仍然使用相同的 Java SE 规范,具备全部相同的类和方法,不一样于从 Java 12 移动到 13。
除此以外,Oracle 的另外一个声明也十分值得咱们关注。声明透露出的消息是,若是坚持使用 Java 11 并计划在下一个 LTS 版本(即 Java 17)发布时再进行升级,开发者可能会发现本身的项目代码没法经过编译。因此请记住,Java 新的开发规则如今声明能够在一个版本中弃用某个 API 方法,并在下一个版本中删除它。
640?wx_fmt=png
采用新版本 Java 的注意事项
在本节中,将概述在采用新版本 Java 以前必须考虑的一些注意事项/风险。
被新版本系列“绑定”
若是采用了 Java 12 并使用新的语言特性或新的 API,这意味着实际上你已将项目绑定到 Java 的新版本系列。接下来你必须采用 Java 13, 14, 15, 16 和 17,而且必须在下一个版本发布后的一个月内采用每一个新版本。
使用了新版本,每一个版本的使用寿命为六个月,而且在发布后仅七个月就过期了。这是由于每一个版本只有在六个月内提供安全补丁,发布后1个月的第一个补丁和发布后4个月的第二个补丁。7个月后,下一组安全补丁会发布,但旧版本不能获取更新。
所以,你要判断自身的开发流程是否容许升级 Java 版本,时间窗口方面会不会太狭窄?
升级的“绊脚石”
实际使用中有不少阻止咱们升级 Java 的因素,下面列出一些常见的:
开发资源不足:你的团队可能会很是忙碌或规模过小,你能保证两年后从 Java 15 升级到 16 的开发时间吗?
构建工具和 IDE:你使用的 IDE 是否会在发布当天支持每一个新版本?Maven? Gradle 呢? 若是不是,你有后备计划吗?请记住,你只有1个月的时间来完成升级、测试并将其发布到生产环境中。此外还包括 Checkstyle,JaCoCo,PMD,SpotBugs 等等其余工具。
依赖关系:你的依赖关系是否都准备好用于每一个新版本?请记住,它不只仅是直接依赖项,而是技术堆栈中的全部内容。字节码操做库尤为受到影响,例如 ByteBuddy 和 ASM。
框架:这是另外一种依赖,可是一个大而重要的依赖。在一个月的狭窄时间窗口内,Spring 会每六个月发布一个新版本吗? Jakarta EE(之前的 Java EE)会吗?若是它们不这样作会怎么样?
云 / 托管 / 部署
你是否能够控制代码在生产环境中的运行位置和方式?例如,若是你在 AWS Lambda 中运行代码,则没法控制。AWS Lambda 没有采用 Java 9或10,甚至没有采用 Java 11。因此除非 AWS 提供公共保证以支持每一个新的 Java 版本,不然根本没法采用 Java 12。
如何托管你的 CI 系统?Jenkins, Travis, Circle, Shippable, GitLab 会快速更新吗?若是不是,你会怎么作?
对将来的预测
若是已经阅读了上面的列表,而且你的代码和流程能够应对。这十分好,但更重要的是要明白,你也在限制将来进行改变的能力。例如,你的代码可能今天不在 AWS Lambda 上运行,但将来三年呢?
为采用新版本进行规划
若是正在考虑采用新版本的 Java,建议你准备一份如今所依赖的全部内容的清单,或者可能在将来3年内会依赖的。你须要保证该列表中的全部内容都能正常工做,并与新版本一块儿升级,或者若是该依赖项再也不更新,请制定好计划。做者提供了他的清单:
Amazon AWS
Eclipse
IntelliJ
Travis CI
Shippable CI
Maven
Maven plugins (compile, jar, source, javadoc, etc)
Checkstyle, 以及相关的 IDE 插件和 maven 插件
JaCoCo, 以及相关的 IDE 插件和 maven 插件
PMD 和相关的 maven 插件
SpotBugs 和相关的 maven 插件
OSGi bundle metadata tool
Bytecode 工具(Byte buddy / ASM etc)
超过 100 个 jar 包依赖项
说了这么多,做者固然不是鼓励你们不进行升级,新语言特性带来的好处以及性能加强会让开发者受益,但升级背后的风险也应该考虑进去。
其余第三方产商的声明
Spring 框架已经在视频中表达了对 Java 12 的策略。关键部分是:
“Java 8 和 11 做为 LTS 版本会持续得到咱们的正式支持,对于过渡版本,咱们也会尽最大努力支持。若是你升级到 Java 11,咱们很是愿意和你合做,但它们不会得到正式的生产环境支持。由于长期支持版本才是咱们关注的重心,对于 Java 12 及更高版本咱们会尽最大的努力。”
做为典型软件供应商的一个例子,Liferay 声明以下:
Liferay 已决定不会对 JDK 的每一个主要版本进行认证。咱们将选择遵循 Oracle 的主导并仅认证标记为 LTS 的版本。—— Liferay 博客
640?wx_fmt=png
总结
相信确定已经有开发团队采用了新版本的 Java,但但愿他们是通过思考判断以后作出的决定。除了文章中提到的问题,还会有不少其余在升级前须要思考的因素,欢迎在评论中留下你的见解。