eclipse-emfcloud / emfjson-jackson

emfjson-jackson
Other
17 stars 15 forks source link

`ObjectMapper`s with `EMFModule` are not thread-safe #56

Closed janhicken closed 2 years ago

janhicken commented 2 years ago

The EMFModule, specifically the EObjectPropertyMap.Builder, uses an instance of WeakHashMap for caching purposes internally.

Normally, ObjectMappers are thread-safe and can thus be used by different threads for concurrent processing. As soon as the EMFModule is added to the mapper, this property no longer holds true.

Here is an exemplary stack trace of a thread, that hangs in WeakHashMap.get, because its memory was corrupted by concurrent use before.

  at java.base@17.0.2/java.util.WeakHashMap.get(WeakHashMap.java:409)
  at app//org.eclipse.emfcloud.jackson.databind.property.EObjectPropertyMap$Builder.construct(EObjectPropertyMap.java:84)
  at app//org.eclipse.emfcloud.jackson.databind.property.EObjectPropertyMap$Builder.lambda$buildCache$3(EObjectPropertyMap.java:104)
  at app//org.eclipse.emfcloud.jackson.databind.property.EObjectPropertyMap$Builder$$Lambda$463/0x000000080159a4a8.accept(Unknown Source)
  at java.base@17.0.2/java.lang.Iterable.forEach(Iterable.java:75)
  at app//org.eclipse.emfcloud.jackson.databind.property.EObjectPropertyMap$Builder.buildCache(EObjectPropertyMap.java:104)
  at app//org.eclipse.emfcloud.jackson.databind.property.EObjectPropertyMap$Builder.construct(EObjectPropertyMap.java:81)
  at app//org.eclipse.emfcloud.jackson.databind.property.EObjectPropertyMap$Builder.constructDefault(EObjectPropertyMap.java:207)
  at app//org.eclipse.emfcloud.jackson.databind.deser.EObjectDeserializer.deserialize(EObjectDeserializer.java:74)
  at app//org.eclipse.emfcloud.jackson.databind.deser.EObjectDeserializer.deserialize(EObjectDeserializer.java:39)
  at app//org.eclipse.emfcloud.jackson.databind.deser.ResourceDeserializer.deserialize(ResourceDeserializer.java:74)
  at app//org.eclipse.emfcloud.jackson.databind.deser.ResourceDeserializer.deserialize(ResourceDeserializer.java:30)
  at app//com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:324)
  at app//com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2051)
  at app//com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1670)

In a nutshell, using an ObjectMapper with an EMFModule across multiple threads can result in the application to hang indefinitely.