정확히는 Azul사의 문제는 아니지만 상용 제품인 Zing이 있어 먼저 나에게 타겟이 된 것뿐입니다.
좀 더 정확히는 OpenJDK를 기반으로 하는 또는 TCK(Java Technology Certification Kit)를 통과한
벤더사별 JDK가 문제가 있는 것 같습니다.
회사 업무상 최신 JDK를 사용할 수 없으나 현재 테스트한(게시한 날짜 기준) 버전은(1.8, 11, 12)
Linux, Windows O/S상관없이 전부 문제가 있었습니다.
Zulu JDK를 테스트 한 이유는 당연히 Oracle JDK 요료화 때문이지요.
테스트에 문제가 있었던 내용은 바로 DecimalFormat, NumberFormat 클래스등의 RoundingMode 반올림(HALF_UP)에
심각한 버그입니다.
(부동소숫점 문제를 떠나 같은 소스코드 기준으로 Oracle JDK(1.7)와 Oracle/OpenJDK(1.8)를 기반으로 하는 벤더사별 JDK의 결과 값이 맞지 않는다가 문제입니다. )
Azul 쪽에 메일도 보냈는데 1개월이 지나도 답이 없고 개발 커뮤니티 관련 내용 게시도 했는데 별다른 답변은 없는 것 같습니다.
혹 OpenJDK를 기반으로 하는 각 벤더사별 JDK를 Oracle JDK 대안으로 생각하고 현업에 적용하실 계획이 있는 분들은
좀 더 지켜보시거나 많은 테스트를 해보신 후 적용해하시기 바랍니다.(일반 커뮤니티는 문제가 없겠지만.. 금융, 평가, 분석 등은 문제가...)
** 테스트 JDK **
Zulu JDK, Zing JDK, AdoptOpenJDK, Amazon Corretto, RedHat JDK, OpenJDK
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
문제가 되는 아주 간단한 테스트 코드(1.8이상의 JDK에서 문제가 발생하네요. ORACLE JDK도 문제고요)
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class RoundTest
{
public static void main(String[] args)
{
double rnd;
System.out.println("** DecimalFormat");
DecimalFormat df = new DecimalFormat("#,###.00");
df.setRoundingMode(RoundingMode.HALF_UP);
df.setMaximumFractionDigits(2);
rnd = 212399.535d;
System.out.println(df.format(rnd));
rnd = 112399.405d;
System.out.println(df.format(rnd));
}
}
## 결과값 (Oracle JDK)
** DecimalFormat
212,399.54
112,399.41
## 결과값 (Azul Zulu JDK)
** DecimalFormat
212,399.54
112,399.40
https://docs.oracle.com/javase/6/docs/api/java/math/RoundingMode.html
https://devdocs.io/openjdk~8/java/math/rounding
HALF_UP API문서를 보면 문제는 없어 보입니다.
만약 이런 문제를 안고라도 OpenJDK를 사용하시겠다면
우선 BigDecimal 변경해서 처리해야 될 것 같습니다.
BigDecimal bd = BigDecimal.valueOf(rnd);
bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(df.format(bd)); --> 112,399.41
Azul사에 한번더 문의하니 바로 답변 해주시네요.