From fcead670f034aa36b53545e11dda10bee48b3bfb 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 37139cb7334..30bbdb3afa4 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; } /**