Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StdSubtypeResolver is not thread safe (possibly due to copy not being made with ObjectMapper.copy()) #2755

Closed
tjwilson90 opened this issue Jun 10, 2020 · 5 comments
Milestone

Comments

@tjwilson90
Copy link

Version 2.11.0

java.util.ConcurrentModificationException
	at java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719)
	at java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:741)
	at com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver.collectAndResolveSubtypesByTypeId(StdSubtypeResolver.java:194)
	at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findTypeDeserializer(BasicDeserializerFactory.java:1597)
	at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:497)
	at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4669)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4478)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3471)
@cowtowncoder
Copy link
Member

That is very odd: there should be no way that particular StdSubTypeResolver instance would be used concurrently in a way for this to happen, since underlying Set is _registeredSubtypes and that is only assigned during configuration of ObjectMapper, but not changed when mapper is being used (it must be set before usage).

So this is somehow due to specific usage. Two possibilities come to mind:

  1. Something tries to re-configure ObjectMapper at point when it is already being used (not supported usage, but 2.x can not really prevent -- 3.0 makes this impossible)
  2. A copy is made with ObjectMapper.copy(), but StdSubtypeResolver isn't copied, and thereby mapper instances remain coupled

It would be important to know what causes this, to be able to reproduce the problem.
That would allow fixing it (if it's (2)) or at least pointing out problems with usage (if (1)).
Or possible something else I didn't think of.

@tjwilson90
Copy link
Author

The codebase I'm seeing in does make potentially concurrent ObjectMapper.copy() calls on the same ObjectMapper, so that hypothesis seems likely. I don't see any re-configuration.

@cowtowncoder
Copy link
Member

@tjwilson90 Ok good, thank you for verifying this. In that case I think copy() operation needs to make copy of StdSubtypeResolver to avoid this problem. It'd be great to have a unit test to show the issue, but these are bit involved to do. Maybe

src/test/java/com/fasterxml/jackson/databind/misc/ThreadSafety1759Test.java

could be used as an example to build a (at least sometimes?) failing case.

@cowtowncoder cowtowncoder changed the title StdSubtypeResolver isn't thread safe StdSubtypeResolver isn't thread safe (possibly due to copy not being made with ObjectMapper.copy()) Jun 10, 2020
@cowtowncoder cowtowncoder changed the title StdSubtypeResolver isn't thread safe (possibly due to copy not being made with ObjectMapper.copy()) StdSubtypeResolver is not thread safe (possibly due to copy not being made with ObjectMapper.copy()) Jun 12, 2020
@cowtowncoder cowtowncoder removed the 2.12 label Jun 12, 2020
@cowtowncoder cowtowncoder modified the milestones: 2.10.0, 2.11.1 Jun 12, 2020
@cowtowncoder
Copy link
Member

Fixed for 2.11.1 and 2.12.0; 3.0 (master) would not have this problem (SubTypeResolver already snapshottable).

@tjwilson90
Copy link
Author

Thanks for the quick turnaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants