-
Bug
-
Resolution: Fixed
-
P4
-
None
-
master
The following example shows an NPE in CLDRTimeZoneNameProviderImpl after downgrading the tzdata version from 2025b to 2025a.
2025b added a new time zone, America/Coyhaique. I think what's happening here is that sun.util.resources.cldr.TimeZoneNames is generated at built-time with a reference to the new zone, and at runtime sun.util.calendar.ZoneInfo.getTimeZone uses the older tzdata and returns null. BeforeJDK-8342550, the logic in CLDRTimeZoneNameProviderImpl used java.util.TimeZone.getTimeZone, which has fallback logic to return a non-null logic for the unknown zone and avoids the crash.
Note that the repro below requires passing 'tzupdater -f' to downgrade the version, otherwise it reports "Current JRE has later version (tzdata2025b) than the tzupdater provided one (tzdata2025a)." This suggests that downgrading tzdata versions in this way may not be a supported use-case, but I wanted to report this to confirm whether that's the case. This did previously work without the crash, even if it was a bad idea.
$ cat T.java
import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.Locale;
class T {
public static void main(String[] args) {
System.err.println(DateFormatSymbols.getInstance(Locale.US).getZoneStrings().length);
}
}
$ javac T.java
$ ./jdk25/bin/java T
632
$ ./jdk25/bin/java -jar /tmp/tzupdater.jar -V
tzupdater version 2.3.3-b02
JRE tzdata version: tzdata2025b
tzupdater tool would update with tzdata version: tzdata2025b
$ ./jdk25/bin/java -jar /tmp/tzupdater.jar -f -l https://data.iana.org/time-zones/releases/tzcode2025a.tar.gz
Using https://data.iana.org/time-zones/releases/tzcode2025a.tar.gz as source for tzdata bundle.
WARNING: Use of the three-letter time zone ID "NST" is deprecated and it will be removed in a future release
java.lang.RuntimeException: Invalid TimeZone ID: NST
$ ./jdk25/bin/java T
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.util.TimeZone.toZoneId()" because the return value of "sun.util.calendar.ZoneInfo.getTimeZone(String)" is null
at java.base/sun.util.cldr.CLDRTimeZoneNameProviderImpl.deriveFallbackNames(CLDRTimeZoneNameProviderImpl.java:135)
at java.base/sun.util.cldr.CLDRTimeZoneNameProviderImpl.getZoneStrings(CLDRTimeZoneNameProviderImpl.java:128)
at java.base/sun.util.locale.provider.TimeZoneNameUtility.loadZoneStrings(TimeZoneNameUtility.java:86)
at java.base/sun.util.locale.provider.TimeZoneNameUtility.getZoneStrings(TimeZoneNameUtility.java:72)
at java.base/java.text.DateFormatSymbols.getZoneStringsImpl(DateFormatSymbols.java:849)
at java.base/java.text.DateFormatSymbols.getZoneStrings(DateFormatSymbols.java:564)
at T.main(T.java:7)
2025b added a new time zone, America/Coyhaique. I think what's happening here is that sun.util.resources.cldr.TimeZoneNames is generated at built-time with a reference to the new zone, and at runtime sun.util.calendar.ZoneInfo.getTimeZone uses the older tzdata and returns null. Before
Note that the repro below requires passing 'tzupdater -f' to downgrade the version, otherwise it reports "Current JRE has later version (tzdata2025b) than the tzupdater provided one (tzdata2025a)." This suggests that downgrading tzdata versions in this way may not be a supported use-case, but I wanted to report this to confirm whether that's the case. This did previously work without the crash, even if it was a bad idea.
$ cat T.java
import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.Locale;
class T {
public static void main(String[] args) {
System.err.println(DateFormatSymbols.getInstance(Locale.US).getZoneStrings().length);
}
}
$ javac T.java
$ ./jdk25/bin/java T
632
$ ./jdk25/bin/java -jar /tmp/tzupdater.jar -V
tzupdater version 2.3.3-b02
JRE tzdata version: tzdata2025b
tzupdater tool would update with tzdata version: tzdata2025b
$ ./jdk25/bin/java -jar /tmp/tzupdater.jar -f -l https://data.iana.org/time-zones/releases/tzcode2025a.tar.gz
Using https://data.iana.org/time-zones/releases/tzcode2025a.tar.gz as source for tzdata bundle.
WARNING: Use of the three-letter time zone ID "NST" is deprecated and it will be removed in a future release
java.lang.RuntimeException: Invalid TimeZone ID: NST
$ ./jdk25/bin/java T
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.util.TimeZone.toZoneId()" because the return value of "sun.util.calendar.ZoneInfo.getTimeZone(String)" is null
at java.base/sun.util.cldr.CLDRTimeZoneNameProviderImpl.deriveFallbackNames(CLDRTimeZoneNameProviderImpl.java:135)
at java.base/sun.util.cldr.CLDRTimeZoneNameProviderImpl.getZoneStrings(CLDRTimeZoneNameProviderImpl.java:128)
at java.base/sun.util.locale.provider.TimeZoneNameUtility.loadZoneStrings(TimeZoneNameUtility.java:86)
at java.base/sun.util.locale.provider.TimeZoneNameUtility.getZoneStrings(TimeZoneNameUtility.java:72)
at java.base/java.text.DateFormatSymbols.getZoneStringsImpl(DateFormatSymbols.java:849)
at java.base/java.text.DateFormatSymbols.getZoneStrings(DateFormatSymbols.java:564)
at T.main(T.java:7)
- relates to
-
JDK-8342550 Log warning for using JDK1.1 compatible time zone IDs for future removal
-
- Resolved
-
- links to
-
Commit(master) openjdk/jdk/5f00c877
-
Review(master) openjdk/jdk/25130