Help! My Java Locale is Wrong in JDK11!

We discovered this issue when a user from the Netherlands reported that, upon upgrading to Java 11, his application now reported that the week started on Sunday. This is incorrect for the Netherlands, but the real issue was the change of behavior.

With JDK11, Java now loads locales differently. https://www.oracle.com/technetwork/java/javase/documentation/java11locales-5069639.html#providers details the loading behavior for JDK11, and how it supersedes previous versions. Notably, CLDR, or classloaded entries, now go before COMPAT, or things included with the JDK. This can lead to incorrect behavior with complex classpaths.

To supersede this setting, the java.locale.providers system setting is used. It’s a comma-separated list of values, where the possible values are the providers in the blog post above. The default value is CLDR,COMPAT,HOST,JRE where JRE is also COMPAT. The value that I would have expected is COMPAT,HOST,CLDR, where it uses the built-in locales first (from JDK9!), then the host locales, then the classloader locales. Setting -Djava.locale.providers=COMPAT will cause the JDK11 locale loader to act like the JDK9 locale loader.

One thought on “Help! My Java Locale is Wrong in JDK11!”

  1. “CLDR” doesn’t mean “classloaded entries”, it’s the Unicode Consortium CLDR archive (the jdk 11 uses the release 33). It makes sense to keep it first since it is shared by many runtime and will be constantly updated.

    In the reported Netherlands case, my guess is that the developer only provided a language code without providing a country code. The country defines the first day of the week, not the language:

    for (var tag : Set.of("nl", "nl-NL")) {
    var locale = Locale.forLanguageTag(tag);
    System.out.println(locale + ": " + new GregorianCalendar(locale).getFirstDayOfWeek());
    }

    gives

    nl: 1
    nl_NL: 2

Leave a Reply