JDK8 到 JDK11 版本迁移指南 - Tencent/TencentKona-11 GitHub Wiki

1. 简介

本文档旨在帮助由 Tencent Kona JDK 8 迁移至 Tencent Kona JDK 11 的工程师,评估和发现可能的兼容问题,并提供相应解决建议和经验,如果您想了解迁移到 JDK 11 的业务价值,请参考 Tencent Kona 团队的相关分享。

本文档主要内容包括:

  • JDK 11 功能和结构变化
  • JDK 打包类库的变化
  • JVM GC 等基础机制变化
  • 具体的 step-by-step 迁移指导

注意:

  • 考虑到生产实际,本文对比基于 Tencent Kona JDK 11 vs Tencent Kona JDK 8,对比项细节将明确标记出
  • 本文列出的是可能的兼容性影响,因此会更加集中于原有功能的移除和修改,而不会侧重介绍 ZGC 等新特性

2. 兼容性变化

2.1. 功能和文件结构变化

事项
文件结构变化
说明
JDK配置文件

将散落在JDK各个子目录的配置文件,例如安全策略配置等,都集中到新添加的conf目录下

jdk-11.0.2.jdk/Contents/Home/conf
├── logging.properties
├── management
│   ├── jmxremote.access
│   ├── jmxremote.password.template
│   └── management.properties
├── net.properties
├── security
│   ├── java.policy
│   ├── java.security
│   └── policy
│       ├── README.txt
│       ├── limited
│       │   ├── default_US_export.policy
│       │   ├── default_local.policy
│       │   └── exempt_local.policy
│       └── unlimited
│           ├── default_US_export.policy
│           └── default_local.policy
└── sound.properties
请检查应用是否有对相关配置的依赖
JRE ${JAVA_HOME}/jre被移除
ClassLoader扩展机制 ${JAVA_HOME}/lib/ext被移除 ExtClassloader目前被重构为PlatformClassloader,并且类型不再是URLClassloader
javah ${JAVA_HOME}/bin/javah被移除

可以使用

javac -h
Corba相关工具
  • idlj
  • orbd
  • servertool
  • tnamesrv

Web Service相关工具
  • schemagen
  • wsgen
  • wsimport
  • xjc

2.2 Java API 变化

2.2.1 Java 平台模块化系统(JPMS)

JDK 9引入的JPMS,以及对JDK自身进行的重构,往往是最大的兼容性难点来源,模块化引入的封装,虽然提供了隔离性、安全性等好处,但随之而来的Readability和Accessability也会影响一些基础机制:

  • 应用运行时反射访问Java public/internal API,可能被禁止,解决办法是

    // 也可以设置 deny 或 warn 来进行排查
    --illegal-access=permit
    
    // 或者使用 --add-open 来解决反射 accessiblity 限制
    // 例如:
    java --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED -jar jython-standalone-2.7.0.jar
  • 应用代码引用非Java Public API,则会面临编译期和运行时两个阶段的兼容问题

    // 可以使用下面的命令给javac或者java命令,解决编译期/运行时困难
    --add-exports java.management/sun.management=ALL-UNNAMED

2.2.2. sun.misc.Unsafe 等 internal API

虽然是 Internal API,但当时很多开源软件和应用对此有依赖,从 ProtoBuf、netty 再到 Cassandra,都难以避免,最好的办法是去查找相关项目的 JDK 11 支持版本。

  • Unsafe.monitorEnter()/monitorExit 等 API 被移除,可以使用 concurent API 替代
  • Base64Encoder/Decoder 等可以替换为 java.util.Base64
  • 其他一些能力被 VarHandle API 取代,更加安全和强大

2.2.3. Java EE 和 Corba 模块(Module)已经从 JDK 移除

这些都是 JDK 9 中即标记过时(Deprecated)的类库,从业界移植经验看总体影响非常有限。

  • java.xml.ws: Java API for XML Web Services (JAX-WS)
  • java.xml.bind: Java Architecture for XML Binding (JAXB)
  • java.xml.ws.annotation
  • java.corba: CORBA
  • java.transaction: Java Transaction API的子集,以支持CORBA Object Transaction Services
  • java.activation: JavaBeans Activation Framework
  • java.se.ee: 它是一个聚合模块,包含以上6个模块
  • jdk.xml.ws: JAX-WS工具
  • jdk.xml.bind: JAXB工具

如果产品恰好有相关依赖,仍然可以在 Maven Central 获得相关模块,请参考 JEP 320: Remove the Java EE and CORBA Modules

2.3 JVM 内部机制变化

2.3.1. GC(垃圾收集)

JDK 9 开始,OpenJDK 默认 GC 已经替换为 G1 GC,JDK 8 则是 Parallel GC,兼容性影响主要体现在:

  • G1 GC 的 Memory Overhead 略高、初始化时间略长(总体影响应该是在 ms 级别,通常不会影响到生产负载)

绝大部分应用会自己指定 JVM GC 等参数,所以通常不会有明显影响,JDK 11 的 G1 GC 相比 JDK8,在吞吐量和延迟等方面甚至有很大提升,但仍需进行实际业务验证,以确保是否有特定场景的 regression。

gc log的参数设置也发生了变化

旧参数 新参数
PrintGC -Xlog:gc
PrintGCDetails -Xlog:gc*
PrintGCApplicationConcurrentTime PrintGCApplicationStoppedTime -Xlog:safepoint
PrintGCCause 不需要加格外参数,开启gc tag就有
PrintGCDateStamps decorators里设置
PrintReferenceGC -Xlog:ref*=debug
PrintHeapAtGC -Xlog:gc+heap=trace
PrintAdaptiveSizePolicy -Xlog:ergo*=debug
G1PrintHeapRegions -Xlog:gc+region=trace
PrintTenuringDistribution -Xlog:gc+age*=trace
2.3.1.1. ZGC

ZGC 的堆申请和传统的 GC 有所不同,需要占用的 memory mapping 数目更多,即每个 ZPage 需要 mmap 映射三次,这样系统中仅Java Heap 所占用的 mmap 个数为 (xmx / zpage_size) * 3,默认情况下 zpage_size 为 2M。

而为了给 jni 等 native 模块 mmap 映射留出空间,内存映射的数目应该调整为 (xmx / zpage_size) * 3 * 1.2。

默认的系统 memory mapping 数目由文件 /proc/sys/vm/max_map_count 指定,通常数目为 65536,当给 JVM 配置一个很大的堆时,需要调整该文件的配置,使得其大于 (xmx / zpage_size) * 3 * 1.2。

3. 如何开展 JDK 迁移工作

3.1 建议步骤

  • 获取 Tencent Kona JDK 11 最新版本

  • 使用 java 11

    `jdeps --jdk-internals -R --class-path 'libs/*' $project`
  • 尝试运行应用程序,发现可能的兼容问题

  • 如果有,则尝试解决兼容问题:

    • 参考上一章节调整 JVM 参数等
    • 升级第三方软件包
    • 尝试重新编译
  • 运行和测试应用程序

3.2 目前落地案例分享

大数据与云计算的新引擎 – Kona JDK 11揭秘

4. 获取 Tencent Kona JDK 11

访问 GitHub Release Page

5. 参考

⚠️ **GitHub.com Fallback** ⚠️