java8升级java12
传统上,企业一直不愿升级到最新版本的Java,直到它得到充分的证明。 自从Java 9于2017年9月问世以来,我们每六个月就有一个新版本的Java变得越来越具有挑战性。因此,即使Java 9不到两年,最新版本现在还是Java 12。
这种变化的步伐可能令人生畏,而且看起来好像要从大多数应用程序仍在运行的 Java 8升级到Java 12可能需要做很多工作。 在本文中,我们将研究:
在深入探讨如何升级之前,我们应该认真考虑为什么要升级。
作为开发人员,我们对语言的每次更新中附带的新语言功能或API最为感兴趣。 自Java 8以来,我们拥有许多新功能,并且还有一些可以改变我们工作方式的新工具。 我已经挑选出一些关键功能,开发人员告诉我,当他们使用最新版本的Java时,他们的工作变得更加轻松。
局部变量类型推断 ( var
)是语法糖的一个很好的示例,它有助于减少样板代码。 它不是所有可读性问题的全部解决方案,但是在正确的时间使用它可以帮助代码阅读者专注于业务逻辑(正在做的事情)而不是样板(如何做)。
便利的工厂集合方法使创建列表,地图和集合等集合变得更加容易。 工厂方法还会创建无法修改的集合,从而使它们更安全地使用。
可以使用新的Collector for Streams操作将结果收集到不可修改的集合中,以将结果放入不可变的集合中。
Predicate :: not提供了一种否定谓词lambda或方法引用的简便方法,从而再次减少了我们代码中的样板。
当使用Optional而不是笨拙的if语句时,Optional的新方法为函数式编码提供了更多选择。
JShell是REPL ,它允许我们在Java中运行单独的代码行,甚至脚本。 这是尝试新功能的好方法,我们可以在开发机器上本地使用它,而不必在生产应用程序代码中采用Java的新版本。
JDK内置的HttpClient 。 几乎每个人都通过Web应用程序或REST服务或其他方式使用某种形式的HTTP。 内置客户端消除了对外部依赖项的需求,并支持具有同步和异步编程模型的HTTP 1.1和2。
多版本jar文件是开发人员可以用来满足使用Java最新版本以及被迫使用旧版本的需求的工具库之一。
JLink是Java模块系统提供的一种出色的工具,它使我们仅打包和部署我们真正需要的JDK部分。
一般而言,每个新版本的性能都比前一个版本好。 “更好”可以采用多种形式,但是在最近的发行版中,我们看到了启动时间的缩短。 减少内存使用; 以及使用特定的CPU指令导致代码使用更少的CPU周期等。 Java 9、10、11和12都对Garbage Collection进行了重大更改和改进,包括将默认Garbage Collector更改为G1 ,对G1进行了改进,以及三个新的实验性Garbage Collector(Java 11中的Epsilon和ZGC ,以及Java中的Shenandoah) 。 12)。 三个似乎过大,但每个收集器针对不同的用例进行了优化,因此,您现在可以选择现代垃圾收集器,其中之一可能具有最适合您的应用程序的配置文件。
Java的最新版本中的改进可以降低成本。 像JLink这样的所有工具中,不仅可以减少我们部署的工件的大小,而且最近在内存使用方面的改进还可以降低我们的云计算成本。
总是有另一个潜在的好处要考虑,因为使用现代版本的语言还可以吸引广泛的开发人员,因为许多开发人员希望有机会学习新知识并提高他们的技能。 使用现代Java版本会影响开发人员的保留和招募,最终会影响团队的运营成本。
自Java 8以来,很多事情发生了变化,而不仅仅是语言功能方面的变化。 Oracle开始发布两个不同的版本,每个版本具有不同的许可证(您需要付费才能在生产中使用的商业版本和开放源代码的OpenJDK版本),并更改了其更新和支持模型。 这在社区中引起了一些混乱,但是最终意味着它给了我们更多的选择 。 我们既要考虑我们的选择,又要考虑JDK的需求。
鉴于最新版本是Java 12,因此似乎有很多版本可以从Java 8升级到该版本。实际上,选择比这要简单一些。 现在,我们每六个月发布一次版本,每个新版本都会替代以前的版本。 唯一的例外是每三年发布一次长期支持(LTS)。 这使组织可以选择自己满意的升级途径-每六个月升级到最新版本,或者每三年进行一次传统风格的大型升级,直到下一个LTS版本。 Java 8是一个LTS,尽管Oracle在今年1月停止提供Java 8的更新以用于(免费)商业用途。 Java 11是当前的LTS,尽管由于Java 12已经发布,Oracle并未为此提供免费的商业更新,但是许多组织提供的JDK至少可以提供三年的更新。
您面临的选择是:升级到最新版本的Java(12),并准备每六个月升级一次; 或升级到最新的LTS(11),让您最多有三年时间考虑下一次升级。 有趣的是,我们希望大型组织从LTS发行版过渡到LTS发行版,而初创公司可能每六个月更新一次。 更快速,可预测的发布节奏的好处在于,它支持两种选择。
Oracle没有为其LTS版本提供免费更新,并不意味着就不可能在生产中运行LTS并获得免费升级。 还有许多其他组织和供应商提供OpenJDK的构建(甚至Oracle商业JDK都基于JDK的参考实现)。 可以在此列表中找到免费的OpenJDK构建程序,免费的公共更新可用的日期以及任何商业支持的详细信息,而不用在这里列举它们。
这似乎比过去更加复杂。 的确有更多因素要考虑,但这是选择更多的副作用。 Java冠军已经准备了关于许可,支持,更新和向我们开放的其他选项的更完整讨论 ,并且QCon London 2019还将针对该主题进行问答环节 。
许多开发人员在考虑从Java 8升级时所关心的主要问题是Java 9中的重大更改,以及担心这些更改可能会破坏应用程序。 更改之一是内部API的封装 ,这意味着JDK中某些可用的方法不再可用。 在Java 9发行时,这连同删除tools.jar和rt.jar似乎令人震惊,但事后看来,对于库,框架和语言开发人员而言,这似乎比对应用程序开发者而言,更是一个问题。
如果您的应用程序没有做它不应该做的事情(例如使用内部API或不推荐使用的方法),则迁移到Java 9或更高版本并不像看上去那样可怕。 实际上,我们使用的构建工具和库已经解决了社区面临的许多问题。
每个升级过程都将特定于要迁移的应用程序。 但是,有一些基本的良好做法将有助于简化流程。 这些步骤以应解决它们的顺序进行了概述,您会发现在前几个步骤中甚至不需要使用更新的JDK。
出现警告是有原因的,如果您阅读它们,它们经常谈论将来可能会消失的功能。 如果您正在Java 8 JDK上使用Java 8,并且看到过时警告或不应使用的功能的警告(请参见图1),请在尝试移至较新的JDK之前修复这些警告。
图1-来自JDK 8的示例编译器警告
请注意,在这个现代的Java世界中,弃用正变得越来越重要,并且Java 10和Java 11都删除了API。
Java 9中发生的变化之一是内部API(主要是那些以sun.misc.*
开头的包中的类)被隐藏了。
有一个工具jdeps ,它是JDK的一部分,可以与-jdkinternals
标志-jdkinternals
运行,以检查一组类是否在使用它不应该使用的东西。 例如,如果我在项目的输出目录中运行以下命令:
> $JAVA_HOME\bin\jdeps -jdkinternals .
然后我得到以下输出:
. -> /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/rt.jar
com.mechanitis.demo.sense.twitter.connector.TwitterOAuth (.)
-> sun.misc.BASE64Encoder JDK internal API (rt.jar)
-> sun.misc.Unsafe JDK internal API (rt.jar)
Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependency on any JDK internal APIs. For the most recent update on JDK internal API replacements, please check: https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
JDK Internal API Suggested Replacement
---------------- ---------------------
sun.misc.BASE64Encoder Use java.util.Base64 @since 1.8
sun.misc.Unsafe See http://openjdk.java.net/jeps/260
该工具不仅可以识别使用内部API的类,还可以建议使用什么。
如果您使用的是Maven或Gradle,则需要升级。
Gradle 5.0引入了对Java 11的支持,因此我们应该至少使用5.0。 当前版本是5.3.1 ,并于上个月发布。
我们需要至少运行3.5.0版( 当前版本是3.6.0 ),并且需要确保Maven编译器插件至少是3.8版:
org.apache.maven.plugins
maven-compiler-plugin
3.8.0
11
您可能已经听说过有关迁移到Java 9或更高版本的一些问题,这些问题是库和框架所面临的(并可能已解决)。 例如,许多框架在底层使用了反射和内部API。 为了使您的应用程序有最大的机会继续正常运行,您应该确保所有依赖项都是最新的。 许多库已经更新为可以与Java 9及更高版本一起使用,并且社区正在不断努力以确保这种情况继续下去。
一些依赖项可能需要替换。 例如,许多库已移至Byte Buddy进行代码生成和代理,因为它可与所有现代Java版本很好地兼容。 在研究向Java 11的迁移时,您必须对依赖项以及它们是否已被更新以支持Java 8以后的版本有很好的了解。
不是JDK核心的API已被删除。 这包括Java EE和Corba模块以及JavaFX 。 通过将正确的库添加到依赖管理中,通常可以直接解决该问题。 例如,将对JAXB的依赖项添加到Gradle或Maven。 JavaFX的情况稍微复杂一些,但是OpenJFX站点上有不错的文档 。
您无需重新编译应用程序即可使用最新版本的Java,这就是语言开发人员为保持向后兼容性而努力工作的部分原因。 您可以使用新的JDK在连续集成环境(例如)中运行应用程序,而无需进行任何代码更改。
对于所有上述所有步骤,我们仍然可以使用Java 8来编译应用程序。 仅当您完成了这些其他步骤后,您才考虑考虑针对Java 11或12进行编译。请记住,如果我们不想使用新功能,则可以使用较低语言版本来编译我们的应用程序,因此我们仍然可以回滚到旧版。 例如,在Maven中:
org.apache.maven.plugins
maven-compiler-plugin
3.8.0
8
或在Gradle中:
sourceCompatibility = JavaVersion.VERSION_1_8
仅当一切正常时,所有测试都将运行并且一切都将在性能方面保持良好状态,并且可能在生产中安全运行一段时间后,才应考虑使用新的语言功能。
还要记住,尽管Java 9发行版完全是关于Java模块系统的,但是即使应用程序已经迁移到支持它的版本,也根本不需要使用它。 但是,如果您对采用模块系统感兴趣,可以在InfoQ上找到有关此模块的教程 。
自Java 8以来,很多事情发生了变化:我们每6个月发布一次; 许可,更新和支持已更改; 从中获取JDK的位置可能已更改。 最重要的是,当然还有一些新的语言功能,包括对Java 9所做的重大更改。但是,现在Java 11取代了Java 8作为最新的LTS,现在主要的库,框架和构建工具都采用了Java 9。最新版本的Java,现在是将应用程序迁移到Java 11或12的好时机。
一旦第一次升级“困难了”,就值得至少每6个月(例如在CI中)在最新版本的Java上测试该应用程序。 在理想的情况下,您甚至可以每六个月使用Java的下一个版本,并可以每六个月使用一次Java新功能,并能够在新功能可用时立即使用它们。
有关从Java 8升级的更多信息,请参见“超越Java 8的生活”演示文稿 。
翻译自: https://www.infoq.com/articles/upgrading-java-8-to-12/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1
java8升级java12