Repository navigation
fix ConcurrentModificationException in AuthXManager token renewal - #4601
Merged
Merged
Conversation
Collaborator
|
HI @insaf021 Meaning will appreciate opening an issue and providing a reproducer/code example to make sure we are dicussing same issue. It will help triage it faster. PR description is hard to read; some formatting will help reviewers navigate faster |
Contributor
Author
|
Opened #4606 with a standalone reproducer: the same enhanced-for plus in-place remove pattern throws ConcurrentModificationException on any synchronizedList, no server needed, and the unit test in this PR errors the same way on current master. Also restructured the description into problem / root cause / fix / testing sections, should be easier to navigate now. |
Collaborator
|
@insaf021 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4606
Problem
AuthXManager.authenticateConnectionsruns on the token-renewal thread and walks aCollections.synchronizedListofWeakReference<Connection>to push the fresh credentials onto each pooled connection. Entries whoseConnectionhas since been garbage collected turn up as cleared references during ordinary pool churn.I ran into it exercising renewal against a pool that had recycled a connection: the renewal walk aborts with
ConcurrentModificationException, so every connection after the cleared entry never receives the renewed credentials and starts failing auth once the old token expires.Root cause
The walk uses an enhanced-for loop and calls
connections.remove(connectionRef)in place whenever it meets a cleared reference:The structural modification bumps the backing
ArrayList'smodCount, and the nextiterator.next()throws.Collections.synchronizedListonly guarantees safe iteration when you synchronise on the list yourself and mutate through the iterator.Fix
Move the loop under
synchronized (connections)and prune cleared references viaIterator.remove(), per thesynchronizedListjavadoc. This also closes the narrower race whereaddConnectionstructurally modifies the list from another thread mid-walk.setCredentialsjust swaps anAtomicReference, so holding the monitor across the loop stays cheap.Testing
Added
authenticateConnectionsPrunesClearedReferences: it seeds the connection list with a clearedWeakReferenceahead of two live connections and drivesauthenticateConnectionsdirectly. On master it errors withConcurrentModificationException; with the fix it passes, the cleared entry is pruned, and both live connections carry the renewed credentials. A standalone snippet showing the same failure shape is in #4606.Note
Medium Risk
Changes authentication credential propagation on the token-renewal path; incorrect locking could affect renewal under pool churn, but the change follows synchronizedList usage and is narrowly scoped.
Overview
Fixes token renewal aborting with
ConcurrentModificationExceptionwhenAuthXManager.authenticateConnectionswalks pooled connections and prunes garbage-collectedWeakReferenceentries.The renewal loop now runs under
synchronized (connections)and drops cleared references withIterator.remove()instead of mutating the list during an enhanced-for iteration. SeveralAuthXManagerfields are markedfinal.Adds
authenticateConnectionsPrunesClearedReferencesto assert cleared weak refs are pruned and live connections still receive renewed credentials.Reviewed by Cursor Bugbot for commit 2533458. Bugbot is set up for automated code reviews on this repo. Configure here.