If I try to serialize an Object as JSON and send it to a RESTful web service with a Quantity property != null, I get the following error
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]-> ... (and so on))
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.loadHttpMethod(ApacheHttpClient4Engine.java:430)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:281)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]-> ... (and so on))
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:694)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
...
(and so on)
That's the simplified entity ...
import javax.measure.Quantity;
import javax.measure.quantity.Mass;
public class Compound {
private Quantity<Mass> regAmount;
public Quantity<Mass> getRegAmount() {
return regAmount;
}
public void setRegAmount(Quantity<Mass> regAmount) {
this.regAmount = regAmount;
}
}
This is an example how I set the value:
Compound compound = new Compound();
double value = 1;
Unit<Mass> unit = Units.KILOGRAM;
Quantity<Mass> quantity = Quantities.getQuantity(value, unit);
compound.setRegAmount(quantity);
and this where the error is thrown (works for all other 20 entities without a Quantity):
Builder builder = ClientBuilder.newClient()
.target(webServiceUrl)
.path(path)
.request(MediaType.APPLICATION_JSON);
Entity<E> e = Entity.json(entity); // works
response = builder.put(e); // error if regAmount != null
Used technologies: Jackson, RestEasy, javax.measure.unit-api (ver. 1.0), tec.units.unit-ri (ver. 1.0.3)
Questions:
Thanks a lot in advance!
I tried some other interface implementation but had no luck.
I found a solution which is good enough for the purpose of a RESTful web service. Therefore, I used a custom Serializer which gives me value and unit of the Quantity and this is actually everything I need to reconstruct the Quantity on the client side.
public class QuantitySerializer<Q extends Quantity<Q>> extends JsonSerializer<Quantity<Q>> {
@Override
public void serialize(Quantity<Q> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
try {
gen.writeNumberField("value", value.getValue().intValue());
gen.writeStringField("unit", value.getUnit().toString());
} catch (NullPointerException e) {}
gen.writeEndObject();
}
}