Alright, though I might dig the old code out from source control that caused these issues.
I think it would be fair to say that even synchronizing on creation there exist circumstances where another thread can modify the internal collections. So best be careful.
Looking at the old code, yes it was actually using a message converter. But only when synchronized on creation.
restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
After that the only interaction with RestTemplate was with this:
return restTemplate.postForObject(url, object, clazz);
This is also the line that eventually throws the exception.
There is of course no interaction with the message converter (we have no local reference to it).
Looking at the stacktrace, and the spring source code, the error occurred at this line:
for (HttpMessageConverter<?> converter : getMessageConverters()) {
So what do we have?
- We have concurrent access to the messageConverters
- If our code didn't do it, then which code did? I don't have an answer. My solution at the time was to create a new RestTemplate every time as performance was not a concern in this app.
So in summary, there are circumstances where things may not be thread safe, certainly if you were to play around with message converters directly. This case though is a strange one, but I thought it would be useful to publish it.