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