Based on https://github.com/spring-projects/spring-security/issues/7224#issuecomment-520936156 by @rwinch:
There appears to be an issue with MockMvc not allowing multiple Threads to operate on the headers at the same time. It happens in Spring Security because the
HeaderWriterFilter
will attempt to write the headers when it completes and just before the response is committed.I pushed a branch named nosecurity that reproduces the issue without Spring Security being used to demonstrate the issue is in MockMvc rather than Spring Security.
Comment From: rstoyanchev
The stacktrace for context:
Caused by: java.util.ConcurrentModificationException
at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719)
at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:742)
at org.springframework.mock.web.HeaderValueHolder.getByName(HeaderValueHolder.java:98)
at org.springframework.mock.web.MockHttpServletResponse.doAddHeaderValue(MockHttpServletResponse.java:617)
at org.springframework.mock.web.MockHttpServletResponse.setHeaderValue(MockHttpServletResponse.java:579)
at org.springframework.mock.web.MockHttpServletResponse.setHeader(MockHttpServletResponse.java:557)
at test.Controller.lambda$nosecurity$0(Controller.java:23)
at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:327)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
It looks like the iteration over keys (for case sensitivity) in HeaderValueHolder.getByName
became unnecessary long ago when LinkedCaseInsensitiveMap
was introduced.