yasson icon indicating copy to clipboard operation
yasson copied to clipboard

(de)serialize Double <-> String

Open nimo23 opened this issue 6 years ago • 8 comments
trafficstars

I get this error when trying to (de)serialize the primitive type double:

13:11:18,793 SEVERE [org.eclipse.yasson.internal.Marshaller] double value cannot be Infinite or NaN
13:11:18,803 SEVERE [org.eclipse.yasson.internal.Marshaller] Generating incomplete JSON
13:11:18,803 ERROR [io.util.EntityTool] javax.json.bind.JsonbException: Internal error: double value cannot be Infinite or NaN

When I change double to Double all works. Am I forced to change all the primitive "double" properties to "Double" only to work with yasson?

Btw, the error log does not show which property makes trouble..but it's a property with the type "double"

nimo23 avatar Aug 12 '19 11:08 nimo23

hi @nimo23, this issue seems to be an exact duplicate of this other issue you raised earlier: https://github.com/eclipse-ee4j/yasson/issues/297

aguibert avatar Aug 12 '19 13:08 aguibert

Am I forced to change all the primitive "double" properties to "Double" only to work with yasson?

No, either one is acceptable. The issue is (as the error message indicates) you can't serialize/deserialize infinite/NaN values into double/Double

aguibert avatar Aug 12 '19 13:08 aguibert

this issue seems to be an exact duplicate of this other issue you raised earlier:

No duplicate, the other was about "show the property which makes trouble".. this issue is about "double/Double conversion"..

You say:

you can't serialize/deserialize infinite/NaN values into double/Double

Is this okay? Why not (de)serializing a NaN value to NaN?

Double test = Double.NaN;

Does it makes sense to convert NaN to what it is: a NaN:

{
..
test: "NaN"
..
}


How should one know beforehand when a Double is NaN or not? Yasson should not stop to (de)serialize a Double if the value is NaN. The information about the Double value should be propagated to the json string and vice versa!

The NaN or Infinty is still a valid information! Why answering with an Yasson- Exception?

nimo23 avatar Aug 12 '19 14:08 nimo23

I actually looked at what Jackson does with such values. Jackson does what it should!


{
  "val1" : "NaN",
  "val2" : 1.0,
  "val3" : 0.0,
  "val4" : "Infinity"
}

Please re-open this issue.

I tried to switch from jackson to yasson..however I found many stumbling blocks which are not really thought through with little logical failures by the yasson maintainers . This issue is one example again..

nimo23 avatar Aug 12 '19 14:08 nimo23

Jackson produces values for infinity and Nan, but these are represented as Strings, not numbers, which would likely break clients that are expecting a number value here.

The JSON-B spec builds on top of the JSON-P spec, and currently the JSON-P spec mandates that these values throw an exception:

    /**
     * Writes the specified value as a JSON number value within the current
     * array, field or root context. The string {@code BigDecimal.valueOf(value).toString()}
     * is used as the text value for writing.
     *
     * @param value a value to be written in current JSON array
     * @return this generator
     * @throws javax.json.JsonException if an i/o error occurs (IOException
     * would be cause of JsonException)
     * @throws JsonGenerationException if this method is not called within an
     *      array or root context.
     * @throws NumberFormatException if the value is Not-a-Number (NaN) or infinity.
     */
    JsonGenerator write(double value);

There is also a more general problem for double values that are outside of the range outside of Java's double primitive. This issue is being discussed at the JSON-P level here: https://github.com/eclipse-ee4j/jsonp/issues/160

So while I think this is a valid topic that needs to be discussed, the proper place to resolve this is at the JSON-P spec level in issue 160, rather than here in Yasson.

aguibert avatar Aug 13 '19 22:08 aguibert

Hi @aguibert,

could Json-B provide a workaround as long as Json-P does not handle NaNand Infinity of Double values correctly?

Yasson should use a Converter internally to provide NaN and Infinty for the Wrapper Double and uses that behind the (de)serializing process when detecting a Double.

Please provide a converter as a workaround or something like this:

Converter for Double to Json-String:

try{
    // normal conversion to double
}
catch(NumberFormatException ex){
    if(val == Double.NaN) return "NaN";
    if(Double.isInfinite(val) && val>0) return "Infinity";
    if(Double.isInfinite(val) && val<0) return "-Infinity";
}

Converter for String to Double:

try{
    if(val == "NaN") return Double.NaN;
    if(val == "Infinity") return Double.POSITIVE_INFINITY;
    if(val == "-Infinity") return Double.NEGATIVE_INFINITY;
    // normal conversion to double
    ...
}

You can remove the converter from Yasson after Json-P supports the wrapper Double:

JsonGenerator write(Double value);

Actually, I cannot use Yasson because it does not handle Double right, I am forced to switch back to Jackson because of this.

nimo23 avatar Aug 14 '19 07:08 nimo23

I don't agree that it should be solved at JSONP level. I think we should consider it as an enhancement for the new JSONB spec or as a Yasson specific feature.

m0mus avatar Aug 26 '19 14:08 m0mus

I am having this issue too and would love for the serialization of Infinity to work correctly similar to Jackson

tsfullman avatar Sep 19 '19 20:09 tsfullman