JDK11升级


为什么要升级

业界

  • Oracle Java 8 的 Support 已经到期,目前每两年出 1 个 LTS 版本,发布节奏快
  • Spring、Netty、Jetty、Kafka 等在 Java 生态非常流行的软件逐渐不兼容 JDK8
  • 从相对权威的生态报告上看,JDK11 的使用占比超过了 JDK8

升级带来的好处

  • 相对JDK 8,11/17 有超过 100+ 新特性,覆盖性能、安全、语法等多个角度
  • 性能方面,在内存、GC、RAS、启动以及新架构 AArch64领域都有明显的优化
  • 对云原生支持更友好,包括 Serverless Java Runtime启动更快,JFR可观测性更优及更多容器支持

新版JDK的特性

  • 压缩String(JDK9)

    String 底层结构优化,使用 byte[],提高内存利用率

  • CodeCache(JDK9)

    除了hotspot中的JIT(C1、C2)外,还有解释器也会生成动态代码

    所有生成的代码会存储在CodeCache里,按照类型划分在不同的区域里,利用cache的局部性对指令进行缓存

    进而降低内存碎片

  • 可伸缩元空间(JDK16)

    降低元空间使用率和碎片化,将空闲的空间归还给OS

  • G1(JDK9)

    高吞吐量、低延迟的GC实现

  • 统一的GC日志(JDK9)

  • 高性能的JFR(JDK11)

    超低开销下的JVM可观测性能力
    关联分析实现方法、对象分配、IO、锁竞争等多维度的热点分析

  • 更精准的NP报错(JDK4)

    在a.b.c这样的链式调用情况下,能更清晰的给出报错的信息

  • 模块化(JDK9)

    目前来看,用处不大

升级挑战

以下是从JDK 8升级到JDK 11会遇到的一些困难:
1.移除的API和功能:自JDK 9以来,一些API和功能已经被弃用并最终在JDK 11中移除,例如Nashorn JavaScript引擎和Java Applets。

2.模块化系统:JDK 9引入了Java平台模块系统(JPMS),这可能会导致依赖问题,需要重新组织代码和库依赖。

3.第三方库和框架的兼容性:可能会遇到第三方库或框架与JDK 11不兼容的情况。需要检查和升级这些依赖项。

4.性能问题:新版本可能会引入性能变化,需要对应用程序做性能测试和调优。

5.工具和插件支持:开发和构建工具可能需要更新以支持JDK 11,例如Maven或Gradle。

6.新的垃圾收集器:JDK 11引入了新的垃圾收集器,例如ZGC和Epsilon。需要理解这些新特性并根据需要调整JVM参数。

7.语法和特性变更:虽然从JDK 8到JDK 11的源代码兼容性相对较好,但一些新特性和改进(如本地变量类型推断)可能需要代码更改来充分利用。

8.安全性和TLS:JDK 11提高了安全性要求,包括对TLS的更新,可能需要调整安全配置。

9.升级成本:升级可能涉及代码更改、测试和部署,这些都增加了工作量和成本。

为了成功升级,您需要执行以下步骤:

  • 更新并测试所有的依赖项以确保兼容性。
  • 使用JDK 11重新编译代码并处理任何编译错误。
  • 对应用进行彻底测试,包括单元测试、集成测试和性能测试。
  • 阅读JDK 8到JDK 11之间所有版本的发布说明,了解重要更改和潜在的影响。
  • 考虑使用工具(如jdeps)分析依赖关系和模块。

升级总是需要仔细规划和执行,但从长远来看,迁移到更现代的Java版本可以带来更好的性能、新特性和改进的安全性。

如何升级

二方包打包问题

jdk11的项目打出来的二方包,为了给其他jdk8的项目用,需要将打出来的包的级别设置为jdk8

在 pom中设置 变量 maven.compiler.source 为8 即可

基础环境配置

  • maven需要升级到3.5.0以上,maven-compiler-plugin升级到3.6.1以上
    待升级的maven项目的pom配置如下
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>3.6.1</version>
 <configuration>
 	<source>11</source>
 	<target>11</target>
 	<encoding>UTF-8</encoding>
 	<useIncrementalCompilation>false</useIncrementalCompilation>
 </configuration>
</plugin>
  <java.version>11</java.version>
  <maven.compiler.source>11</maven.compiler.source>
  <maven.compiler.target>11</maven.compiler.target>
  • Idea 版本要求:intellij版本在2018.2以上
  • Idea的JDK也要升级(使用Idea自己的JDK版本管理功能,下载jdk11即可)
  • Spring 升级
    JDK11对于spring最低版本要求是5.0
  • GC参数改变
  SERVICE_OPTS="${SERVICE_OPTS} -XX:+UseG1GC"
  SERVICE_OPTS="${SERVICE_OPTS} -XX:G1HeapRegionSize=8m"
  SERVICE_OPTS="${SERVICE_OPTS} -XX:+G1BarrierSkipDCQ"
  SERVICE_OPTS="${SERVICE_OPTS} -XX:ErrorFile=/home/admin/logs/hs_err_pid%p.log"
  SERVICE_OPTS="${SERVICE_OPTS} -Xlog:gc*:/home/admin/logs/gc.log"
 # SETENV NEW OPTS
  SERVICE_OPTS="${SERVICE_OPTS} -XX:ReservedCodeCacheSize=256m"
  SERVICE_OPTS="${SERVICE_OPTS} -noverify -DdefaultHsfClientTimeout=3000 -Dpandora.ignore.packaged.plugins=false"
  SERVICE_OPTS="${SERVICE_OPTS} -Djava.awt.headless=true -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=$LOCAL_IP"
  SERVICE_OPTS="${SERVICE_OPTS} --add-exports java.base/jdk.internal.ref=ALL-UNNAMED"
  • 无效的包,需要排除
  • 框架版本要求
    ASM >= 7.0

Guice >= 4.2

guava >= 18.0

lombok >= 1.18.22

MapStruct >= 1.5.5.Final

Kotlin >= 1.3.30

dagger >= 2.24

Mockito >= 2.22.0

Jacoco >= 0.8.3

JMockit >= 1.49

aspectj >= 1.14.0

groovy >= 2.5.6

升级常见问题

  1. 缺少javax相关的包
    JDK11及以上版本,已经没有这些rt.jar了,而用.so文件代替了.
    添加依赖
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.1</version>
</dependency>
  1. lombok问题

升级lombok版本到1.18.22及以上版本.

  1. 无法远程debug

JDK11的DEBUG端口变成了*:PORT的SOCKET形式.

-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n

改为

-agentlib:jdwp=transport=dt_socket,address=*:8000,server=y,suspend=n

参考

1、https://grow.alibaba-inc.com/course/4800015674472669/section/1800015674472769
2、https://ata.atatech.org/articles/11020147240?spm=ata.23639746.0.0.753d21b8aGbM4p
3、https://ata.atatech.org/articles/11020153233


文章作者: 王利康
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 王利康 !
  目录