From 6e508f70d31818916c34d13a538b1fdc803eb274 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 17 Jan 2017 16:43:13 -0500 Subject: [PATCH] Add locking to AbstractRequestExpectationManager This commit ensures that verifying a request, which includes finding and updating expectations, is done synchronously to avoid concurrent modification exceptions. Technically SimpleRequestExpectationManager is not even expected to see concurrent requests by definition but with UnorderedRequestExpectationManager it can happen. Issue: SPR-15029 --- .../AbstractRequestExpectationManager.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java index 41b1f2448c..7b20fdcd3f 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,8 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect private final List requests = new LinkedList<>(); + private final Object lock = new Object(); + protected List getExpectations() { return this.expectations; @@ -66,12 +68,14 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect @Override public ClientHttpResponse validateRequest(ClientHttpRequest request) throws IOException { - if (getRequests().isEmpty()) { - afterExpectationsDeclared(); + synchronized (this.lock) { + if (getRequests().isEmpty()) { + afterExpectationsDeclared(); + } + ClientHttpResponse response = validateRequestInternal(request); + getRequests().add(request); + return response; } - ClientHttpResponse response = validateRequestInternal(request); - getRequests().add(request); - return response; } /**