We upgraded from Oracle JDK 8u77 to 8u92 and suddenly scripts that were previously working no longer work. A minimal reproducer is:
Map<String, Object> attributes = Collections.singletonMap("GROSSREIMBAMOUNT", BigDecimal.ZERO);
String script = "GROSSREIMBAMOUNT.toFixed(2)";
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
for (Entry<String, Object> entry : attributes.entrySet()) {
jsEngine.put(entry.getKey(), entry.getValue());
}
System.out.println(jsEngine.eval(script));
Previously we got
0.00
But now we're getting.
TypeError: GROSSREIMBAMOUNT.toFixed is not a function
typeof
now returns object
where it would previously return number
.
My question is this behavior intentional or a bug? I first though this would be a bug but JDK-8010732 seems to suggest otherwise.
The initial release of Nashorn treated all numeric Java primitives and all subclasses of java.lang.Number as JavaScript numbers. However, JavaScript numbers as defined as doubles, and that means that numeric types that do not map to doubles such as longs or java.lang.BigDecimals will suffer from loss of precision when converted to a JavaScript number.
As you noticed, we fixed this between 8u77 and 8u92. Instances of java.lang.Number that can't be mapped cleanly to doubles are no longer treated as JavaScript numbers in Nashorn.
You have two options to work around this. One is to just treat these numbers as Java objects and use the methods provided by the Java class. This is usually the better option as the Java class was written to work with the numeric type at hand. The other option is to explicitly convert to a JavaScript number. This is usually done by calling the global Number() constructor without the "new" keyword, or by just prepending the unary "+" operator. Note however that this conversion may result in loss of precision without you noticing, so the first option is probably the safer path.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With