I was playing around with Java 9 with the prod code. And I found a couple of Formatting tests failing. After some research, I was able to create a class to reproduce the issue. Which happens in Java 9 but not in Java 8.
The class is here https://pastebin.com/87sA5WMb
import java.text.*;
import java.util.*;
public class FormatFails {
public static void main(String... args){
Currency currency = Currency.getInstance("EUR");
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(Locale.FRANCE);
currencyFormatter.setMaximumFractionDigits(0);
currencyFormatter.setMinimumFractionDigits(0);
currencyFormatter.setCurrency(currency);
String expected = "123 457 €";
String obtained = currencyFormatter.format(123456.789);
System.out.println(expected);
System.out.println(obtained);
System.out.println(expected.equals(obtained));
System.out.format("Bytes from expected: %s\n",Arrays.toString(expected.getBytes()));
System.out.format("Bytes from obtained: %s\n",Arrays.toString(obtained.getBytes()));
}
}
Basically comparing 2 strings:
- An string literal and
- A formatted string in Locale.FRANCE produced using NumberFormat
Using equals on both fails, because of the following:
123 457 €
123 457 €
false
Bytes from expected: [49, 50, 51, -62, -96, 52, 53, 55, 32, -30, -126, -84]
Bytes from obtained: [49, 50, 51, -62, -96, 52, 53, 55, -62, -96, -30, -126, -84]
As you can see there are a different number of bytes and different representation. I don't know how to work around this and more important which is the change in Java9 that is affecting the code.
The result using plain old Java 8 is as follows:
123 457 €
123 457 €
true
Bytes from expected: [49, 50, 51, -62, -96, 52, 53, 55, 32, -30, -126, -84]
Bytes from obtained: [49, 50, 51, -62, -96, 52, 53, 55, 32, -30, -126, -84]
Java 9 version used
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
which is the latest version available.
JDK 9 has moved to use CDLR locale data by default. Links to the JEP and more information on this can be found in the JDK 9 release notes (see http://jdk.java.net/9/release-notes#JDK-8008577). The release note and JEP document the system property can you can use to configure the JDK to use the legacy JRE locale data where needed.