如何使用tzupdater检查和设置Java时区(为openJDK更新tzdata)
如何检查Linux的Java时区。
使用tzupdater设置Java时区的步骤。
在RHEL或者CentOS Linux中为openjdk rpm更新tzdata。
更新tzdata-java rpm以更新Linux中Java的时区。
在Linux中使用tzupdater在Java时区中检查openjdk。
检查openjdk时区。
更新tzdata后是否需要重新启动
在本文中,我将通过示例向我们展示两种检查和设置Java时区(为openJDK更新tzdata)的方法
方法1:使用tzupdater为openJDK更新tzdata
为openJDK更新tzdata的第一种方法是使用ignize TZUpdater工具。
TZUpdater是Oracle的第三方工具,可以从Oracle官方页面下载。
什么是TZUpdater?
提供了TimeZone更新程序工具或者TZUpdater工具,使我们可以使用最新的时区数据来更新已安装的Java开发工具包(JDK)和Java运行时环境(JRE)软件,以适应不同国家的夏令时(DST)更改。
Oracle依靠可通过IANA时区数据库公开获得的时区数据。
在RHEL或者CentOS环境中,我们会找到tzdata rpm,它控制在系统级别应用的时区,而tzdata-java
控制面向Java的应用程序(如openJDK,JRE等)的时区。
提示:
可以使用TZupdater工具,但不需要在RHEL/CentOS环境上设置Java时区,因为tzdata-java可以执行相同的更改,Red Hat也支持并正式发布了该更改。
但是仍然出于本文的目的,我将共享可用于在RHEL/CentOS/SLES或者具有类似源代码的发行版中设置Java时区的步骤。
安装TZUpdater
下载tzupdater存档后,可以使用以下步骤将其解压缩到Linux主机上的任何位置:
# unzip tzupdater-2_2_0.zip Archive: tzupdater-2_2_0.zip creating: tzupdater-2.2.0/ inflating: tzupdater-2.2.0/README inflating: tzupdater-2.2.0/tzupdater.jar
检查Java TimeZone
在更新Java时区之前,我们应该检查现有的tzdata捆绑包,它是OpenJDK rpm的一部分。
使用以下语法:
# cd /root/tzupdater-2.2.0/ # java -jar tzupdater.jar -V | grep version tzupdater version 2.2.0-b01 JRE tzdata version: tzdata2015i tzupdater tool would update with tzdata version: tzdata2019b
所以目前我的OpenJDK包含tzdata2015i,考虑到撰写本文时最新的可用tzdata是2019b,它确实非常旧。
下载tzdata存档
要更新或者设置Java时区,我们接下来必须手动下载tzdata存档。
但是,如果我们只是想使用IANA上最新的可用tzdata存档来更新OpenJDK的tzdata,则无需下载任何存档。
我们只需要一个活动的Internet连接,tzupdater工具将下载最新的tzdata存档并将其安装在openJDK二进制文件中。
要下载不同版本的tzdata,可以查看IANA页面。
使用tzupdater设置Java时区
现在,由于我的系统已连接到Internet,并且希望应用最新的可用tzdata,因此我将执行以下命令来更新或者设置Java时区:
[root@node1 tzupdater-2.2.0]# java -jar tzupdater.jar -l Using https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz as source for tzdata bundle. Failed: java.lang.Exception: Failed while parsing file '/tmp/tz.tmp/asia' on line 1865 'Rule Japan 1948 1951 - Sep Sat>=8 25:00 0 S' java.lang.Exception: Failed while parsing file '/tmp/tz.tmp/asia' on line 1865 'Rule Japan 1948 1951 -Sep Sat>=8 25:00 0 S' at tools.tzdb.TzdbZoneRulesCompiler.parseFile(TzdbZoneRulesCompiler.java:377) at tools.tzdb.TzdbZoneRulesCompiler.compile(TzdbZoneRulesCompiler.java:191) at tools.tzdb.TzdbZoneRulesCompiler.(TzdbZoneRulesCompiler.java:307) at com.sun.tools.tzupdater.ExternalModule.compileToJSRBinary(ExternalModule.java:153) at com.sun.tools.tzupdater.TimezoneUpdater.run(TimezoneUpdater.java:230) at com.sun.tools.tzupdater.TimezoneUpdater.main(TimezoneUpdater.java:634) Caused by: tools.tzdb.DateTimeException: Invalid value for SecondOfDay value: 90000 at tools.tzdb.ChronoField.checkValidValue(ChronoField.java:173) at tools.tzdb.LocalTime.ofSecondOfDay(LocalTime.java:210) at tools.tzdb.TzdbZoneRulesCompiler.parseMonthDayTime(TzdbZoneRulesCompiler.java:475) at tools.tzdb.TzdbZoneRulesCompiler.parseRuleLine(TzdbZoneRulesCompiler.java:399) at tools.tzdb.TzdbZoneRulesCompiler.parseFile(TzdbZoneRulesCompiler.java:354) ... 5 more
其中
-l, --location Compile, test and update JRE timezone data from provided tzdata.tar.gz bundle e.g -l https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz Supported URL protocols : http://, https://, file:// If no URL link is provided, tool will use latest IANA tzdata bundle at: https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz
tzdata2019b中的" asia"时区内容似乎存在一些问题。
如何修复解析文件'/tmp/tz.tmp/asia'时失败?
这必须由tzdata的开发团队解决,但对于我们而言,我们可以使用一种对我也有效的解决方法。
我检查了一些积压和历史记录,结果发现2016d之后发布的所有tzdata都包含针对亚洲时区文件的此问题。
因此我们可以从tzdata 2016d中获取asia
时区文件并将其替换为tzdata2019b
警告:
这些步骤仅用于演示,除非我们知道后果,否则请勿在生产中进行。
与此更改一样,即使OpenJDK具有tzdata2019b,亚洲时区仍将使用tzdata2016d发布的旧数据。
从iana页面下载tzdata2016d
在一个临时位置将其解压缩
# mkdir /tmp/tzdata2016d # cp tzddata2016d.tar.gz /tmp/tzdata2016d # cd /tmp/tzdata2016d # tar -xzvf tzddata2016d.tar.gz
对tzdata2019b重复相同的步骤
# mkdir /tmp/tzdata2019b # cp tzddata2019b.tar.gz /tmp/tzdata2016d # cd /tmp/tzdata2019b # tar -xzvf tzddata2019b.tar.gz
接下来将asia
时区从2016d
替换为2019b
node1:/tmp/tzdata2016d # cp asia ../tzdata2019b/asia node1:/tmp/tzdata2016d # cd ../tzdata2019b/
接下来使用最新更改为2019b
重新创建归档文件
node1:/tmp/tzdata2019b # tar -czvf ../tzdata2019b.tar.gz *
现在让我们重试使用tzupdater工具设置Java时区
node1:/tmp/tzupdater-2.2.0 # java -jar tzupdater.jar -l file:///tmp/tzdata2019b.tar.gz
因此,我们的解决方法起作用了,并且我们已经成功设置了Java时区。
使用file:///tmp/tzdata2019b.tar.gz
作为tzdata包的源。
node1:/tmp/tzupdater-2.2.0 # java -jar tzupdater.jar -V tzupdater version 2.2.0-b01 JRE tzdata version: tzdata2019b tzupdater tool would update with tzdata version: tzdata2019b
重新启动Java应用程序以激活与时区相关的新更改
方法2:使用tzdata-java为openJDK更新tzdata
对于Red Hat/CentOS环境中的OracleJDK,我们也可以使用tzdata-java
rpm,它也将在内部设置Java时区而不会带来任何麻烦。
说明:
在SLES环境中,我们会发现timezone-java
,但这对作为OpenJDK一部分的tzdata版本没有影响,因此我们必须使用tzupdater
当前,我的系统运行的是tzdata rpm的2016e
版本,如下所示:
# rpm -qa | grep tzdata tzdata-java-2016e-3.el7.noarch tzdata-2016e-3.el7.noarch
另外,如果我们使用tzupdater检查Java版本,则我的OpenJDK具有tzdata的2016e
版本
[root@node1 tzupdater-2.2.0]# java -jar tzupdater.jar -V tzupdater version 2.2.0-b01 JRE tzdata version: tzdata2016e tzupdater tool would update with tzdata version: tzdata2019b
接下来,我们将通过从IANA数据库中手动下载rpm将tzdata rpm更新为2019a
说明:
在RHEL系统上,我们必须具有RHN的活动订阅,或者我们可以配置本地脱机存储库," yum"程序包管理器可以使用该本地存储库安装最新的tzdata rpm及其依赖项(如果有)。
[root@node1 tzupdater-2.2.0]# rpm -Uvh /root/tzdata-2019a-1.el7.noarch.rpm warning: /root/tzdata-2019a-1.el7.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY Preparing... ################################# [100%] Updating/installing... 1:tzdata-2019a-1.el7 ################################# [ 50%] Cleaning up/removing... 2:tzdata-2016e-3.el7 ################################# [100%]
并重新验证OpenJDK的tzdata版本,该版本保持不变,因为我们知道tzdata对OracleJDk的tzdata没有影响
[root@node1 tzupdater-2.2.0]# java -jar tzupdater.jar -V tzupdater version 2.2.0-b01 JRE tzdata version: tzdata2016e tzupdater tool would update with tzdata version: tzdata2019b
接下来我们将tzdata-java rpm更新为2019a
[root@node1 tzupdater-2.2.0]# rpm -Uvh /root/tzdata-java-2019a-1.el7.noarch.rpm warning: /root/tzdata-java-2019a-1.el7.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY Preparing... ################################# [100%] Updating/installing... 1:tzdata-java-2019a-1.el7 ################################# [ 50%] Cleaning up/removing... 2:tzdata-java-2016e-3.el7 ################################# [100%]
重新验证OracleJDK的tzdata,如我们所见,现在我们的OpenJDK Java也包含tzdata2019a
[root@node1 tzupdater-2.2.0]# java -jar tzupdater.jar -V tzupdater version 2.2.0-b01 JRE tzdata version: tzdata2019a tzupdater tool would update with tzdata version: tzdata2019b
重新启动Java应用程序以激活与时区相关的新更改
说明:
如我们所见,我们没有遇到方法一中的"亚洲"时区问题,这就是为什么我建议使用RHEL支持的rpm的原因,因为这里解决了这类问题。