Skip to content

Commit d273202

Browse files
authored
Fix ConcurrentModificationException in getDeclaredResources and getResourcesFromProject (#1020)
Add synchronized(syncResources) blocks around iterations in getDeclaredResources() and getResourcesFromProject() to prevent ConcurrentModificationException when the resources list is modified concurrently by another thread. Also changes both methods to iterate over this.resources directly (inside the sync block) instead of this.getResources() which returns an unprotected reference. Fixes #933
1 parent 93b0b9f commit d273202

1 file changed

Lines changed: 15 additions & 11 deletions

File tree

src/main/java/org/jenkins/plugins/lockableresources/LockableResourcesManager.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,15 @@ public List<LockableResource> getReadOnlyResources() {
161161
/** Get declared resources, means only defined in config file (xml or JCaC yaml). */
162162
@Restricted(NoExternalUse.class)
163163
public List<LockableResource> getDeclaredResources() {
164-
ArrayList<LockableResource> declaredResources = new ArrayList<>();
165-
for (LockableResource r : this.getResources()) {
166-
if (!r.isEphemeral() && !r.isNodeResource()) {
167-
declaredResources.add(r);
164+
synchronized (syncResources) {
165+
ArrayList<LockableResource> declaredResources = new ArrayList<>();
166+
for (LockableResource r : this.resources) {
167+
if (!r.isEphemeral() && !r.isNodeResource()) {
168+
declaredResources.add(r);
169+
}
168170
}
171+
return declaredResources;
169172
}
170-
return declaredResources;
171173
}
172174

173175
// ---------------------------------------------------------------------------
@@ -231,14 +233,16 @@ public void setDeclaredResources(List<LockableResource> declaredResources) {
231233
/** Get all resources used by project. */
232234
@Restricted(NoExternalUse.class)
233235
public List<LockableResource> getResourcesFromProject(String fullName) {
234-
List<LockableResource> matching = new ArrayList<>();
235-
for (LockableResource r : this.getResources()) {
236-
String rName = r.getQueueItemProject();
237-
if (rName != null && rName.equals(fullName)) {
238-
matching.add(r);
236+
synchronized (syncResources) {
237+
List<LockableResource> matching = new ArrayList<>();
238+
for (LockableResource r : this.resources) {
239+
String rName = r.getQueueItemProject();
240+
if (rName != null && rName.equals(fullName)) {
241+
matching.add(r);
242+
}
239243
}
244+
return matching;
240245
}
241-
return matching;
242246
}
243247

244248
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)