Details
Description
When using a German localized number with group separators and decimals, a conversion to BigDecimal fails with a NumberFormatException. For German, group separators are dots, decimal separator is a comma (just the other way round of the US version).
In the following test class, the first case is green, the second fails with
org.jbehave.core.steps.ParameterConverters$ParameterConvertionFailed: 1.000.000,01 at org.jbehave.core.steps.ParameterConverters$NumberConverter.convertValue(ParameterConverters.java:256) at de.westlb.jets.xce.jbehave.tools.NumberFormatTest.jbehaveConverter(NumberFormatTest.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99) ... at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: java.lang.NumberFormatException at java.math.BigDecimal.<init>(BigDecimal.java:453) at java.math.BigDecimal.<init>(BigDecimal.java:728) at org.jbehave.core.steps.ParameterConverters$NumberConverter.convertValue(ParameterConverters.java:247) ... 21 more
Putting a breakpoint in the BigDecimal constructor reveals it is fed a String "1.000.000.000.00" which is obviously wrong. I suspect, the "canonicalization" of the original String breaks it.
Test.java
public class NumberFormatTest { private static final BigDecimal EXPECTED = new BigDecimal("1000000.01"); private final String localizedString = "1.000.000,01"; private DecimalFormat germanNumbers; @Before public void setup() { germanNumbers = (DecimalFormat) DecimalFormat .getNumberInstance(Locale.GERMAN); germanNumbers.setParseBigDecimal(true); } @Test public void plainConverter() throws Exception { Number parse = germanNumbers.parse(localizedString); assertEquals(EXPECTED, parse); } @Test public void jbehaveConverter() throws Exception { ParameterConverters.NumberConverter numberConverter = new ParameterConverters.NumberConverter( germanNumbers); Object v = numberConverter.convertValue(localizedString, BigDecimal.class); assertEquals(EXPECTED, v); }
Activity
Mauro Talevi
made changes -
Field | Original Value | New Value |
---|---|---|
Fix Version/s | 3.6 [ 17721 ] | |
Affects Version/s | 3.5.4 [ 18081 ] | |
Affects Version/s | 3.6 [ 17721 ] |
Mauro Talevi
made changes -
Status | Open [ 1 ] | Resolved [ 5 ] |
Resolution | Fixed [ 1 ] |
Mauro Talevi
made changes -
Summary | NumberFormatException when trying to convert parameters to BigDecimal with Locale | NumberFormatException when trying to convert parameters to BigDecimal with German Locale |
The default parameter converters use the default locale of the JVM - that is they are not specified when the Format is created. What is the default locale that you are running under?
Also, the Format objects should not be held as instance variables as they are not thread-safe. Just noticed that writing my own DateParameterConverter yesterday to do relative dates. We should hold the patterns and create the format from the pattern.