Timbo Site

write something


升级JDK

上周日上午碰到了一个有意思的问题:生产环境上为一个用户安排定时任务的时候报错,扔出来的堆栈报错信息如下:

Unexpected error occurred in scheduled task
java.time.zone.ZoneRulesException: Unknown time-zone ID: America/Nuuk
  at java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:272)
  at java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:227)
  at java.time.ZoneRegion.ofId(ZoneRegion.java:120)
  at java.time.ZoneId.of(ZoneId.java:411)
  at java.time.ZoneId.of(ZoneId.java:359)

比较有意思的是这个时区:America/Nuuk

按理来说,在JDK层面应该不会有这种错误,第一想法就是去查这个时区存不存在,结果是有这么个时区的:

还是格陵兰的用户…

记得格陵兰的用户也不少,为什么之前没有这个问题?于是去翻了一下Wikipedia的tzdata列表,下面有一栏写着:

GL +6411-05144 America/Godthab Deprecated -03:00 -02:00 Link to America/Nuuk

时区这东西还能Deprecated啊…

看了一下America/Godthab词条,直接跳到了另一个条目,里面也没写明为什么要换,即使是tzdata2020a的版本变化也没有说明白,只是简单的说了:

To reflect current usage in English better, America/Godthab has been renamed to America/Nuuk. A backwards-compatibility link remains for the old name.

好家伙

看了一眼线上用的jdk版本是8u232,还是2019年10月15日的版本,找到了支持tzdata2020a的补丁提交:[JDK-8243541] (tz) Upgrade time-zone data to tzdata2020a - Java Bug System

Issue Fix Version Assignee Priority Status Resolution Resolved In Build
JDK-8244039 8u271 Kiran Sidhartha Ravikumar P3 Resolved Fixed b01
JDK-8244849 8u261 Kiran Sidhartha Ravikumar P3 Resolved Fixed b07
JDK-8244950 8u260 Kiran Sidhartha Ravikumar P3 Resolved Fixed master

为了确定新的JDK Update能够支持,我在自己机器上用8u292跑了一下这个代码:

LocalDateTime now = LocalDateTime.now();
ZonedDateTime deviceTime = now.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("America/Nuuk"));
System.out.println(deviceTime);

输出正常:

2021-08-16T12:40:52.385-02:00[America/Nuuk]

而换成和生产一致的8u232,则会抛出和最上面一致的出错信息

今天把生产上的Docker Image全换成8u292的之后,回来想了一下,让我主动升级JDK的还有8u162,这个版本把crypto的加密算法Key长度限制放开了。虽在之前用BouncyCastle特殊的AP绕过了这些条条框框,但也免不了后来人用BouncyCastle的JCE实现,本地环境没问题,上生产环境启动直接报错。

Java 8也用了6年,下个月应该要准备上Java 17了