ConcurrentModificationException in camel-jetty DefaultHttpBinding.doWriteResponse

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

ConcurrentModificationException in camel-jetty DefaultHttpBinding.doWriteResponse

I'm running camel 2.15.2 and have been performing some load tests on a jetty consumer component with some POST requests.

My endpoint uri looks like this  

I can consistently produce the stack trace seen below without putting much load on the system (2 threads each sending a request about every 10ms).

Has anyone else seen this? I'm not seeing any real jetty uri options that I can use to tune this further.

2015-11-11 11:21:04,550 WARN  ServletHandler - /pe-eh/v1/event
        at java.util.ArrayList$Itr.checkForComodification(
        at java.util.ArrayList$
        at org.apache.camel.component.http.DefaultHttpBinding.doWriteResponse(
        at org.apache.camel.component.http.DefaultHttpBinding.writeResponse(
        at org.apache.camel.component.jetty.CamelContinuationServlet.service(
        at javax.servlet.http.HttpServlet.service(
        at org.eclipse.jetty.servlet.ServletHolder.handle(
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(
        at org.apache.camel.component.jetty.CamelFilterWrapper.doFilter(

Here appears to be the offending code.
    public void doWriteResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException {
        // set the status code in the response. Default is 200.
        if (message.getHeader(Exchange.HTTP_RESPONSE_CODE) != null) {
            int code = message.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class);
        // set the content type in the response.
        String contentType = MessageHelper.getContentType(message);
        if (contentType != null) {

        // append headers
        // must use entrySet to ensure case of keys is preserved
        for (Map.Entry<String, Object> entry : message.getHeaders().entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            // use an iterator as there can be multiple values. (must not use a delimiter)
            final Iterator<?> it = ObjectHelper.createIterator(value, null);
            while (it.hasNext()) {
                String headerValue = exchange.getContext().getTypeConverter().convertTo(String.class,;
                if (headerValue != null && headerFilterStrategy != null
                        && !headerFilterStrategy.applyFilterToCamelHeaders(key, headerValue, exchange)) {
                    response.addHeader(key, headerValue);

        // write the body.
        if (message.getBody() != null) {
            if (GZIPHelper.isGzip(message)) {
                doWriteGZIPResponse(message, response, exchange);
            } else {
                doWriteDirectResponse(message, response, exchange);