Skip to content

Conversation

@stokito
Copy link
Contributor

@stokito stokito commented Nov 15, 2025

The ChatContainer class has an iteration over list of chat rooms

        for (ChatRoom chatRoom : new ArrayList<>(chatRoomList)) {
           // ...
        }

The new ArrayList<>(chatRoomList allocation is needed to avoid concurrency problems. The chatRoomList is changed in two places: in the addChatRoom() that is synchronized and cleanupChatRoom() that is not synchronized. To avoid problems I made it synchronized too.

@stokito
Copy link
Contributor Author

stokito commented Nov 15, 2025

It looks like some pattern or remains after some refactoring because there are other places with such iteration over an ArrayList copy:
org/jivesoftware/spark/SessionManager.java:206
org/jivesoftware/spark/filetransfer/SparkTransferManager.java:695
org/jivesoftware/spark/ui/ChatRoom.java:1139
org/jivesoftware/spark/ui/ContactGroup.java:270
org/jivesoftware/spark/ui/ContactGroup.java:284
org/jivesoftware/spark/ui/ContactGroup.java:416
org/jivesoftware/spark/ui/ContactList.java:379

@Fishbowler
Copy link
Member

Does that mean that this should go to draft, or should this be tackled in another PR?

@stokito
Copy link
Contributor Author

stokito commented Dec 5, 2025

It creates a copy of the list (new ArrayList<>(this.presenceListeners)) to avoid concurrent modification issues if a listener modifies the list during iteration.

I can't replace all the places where this happens but for listeners we have a few options:

The CopyOnWriteArrayList is already used in some places for listeners also an AI recommended to use it.

So I changed all the places where I found a list of listeners to the CopyOnWriteArrayList so that same pattern will be used everywhere. I can't properly test it but Sparks looks working fine.

@guusdk
Copy link
Member

guusdk commented Jan 5, 2026

Is this fixing an actual problem that someone reported or observed, or is this a theoretical fix? I would very much prefer to have a JIRA ticket for this change, as it seems to be an important change that I'd like to have documented.

@stokito stokito changed the title ChatContainer: avoid allocation of ArrayList SPARK-2378: Make listeners thread safe Jan 6, 2026
@stokito
Copy link
Contributor Author

stokito commented Jan 6, 2026

@guusdk this is not a bug fix and initially I was just confused why the allocation happens. But in fact there may be threading problems in various places. The PR should make the Spark more stable against them but also the code will be more clean and it will use the same pattern everywhere. Currently in most places is used ArrayList with a copy on iteration, in a few places is used the CopyOnWriteArray, in others the synchronized methods.

I created a ticket for this https://igniterealtime.atlassian.net/browse/SPARK-2378

@guusdk
Copy link
Member

guusdk commented Jan 6, 2026

Thanks! Can you rewrite the commit messages to include a reference to that JIRA identifier please (and maybe squash many of the very duplicate commits while you're at it)? That will allow automation to detect which commits belong to which tickets, which is very helpful for future developers.

stokito added 12 commits January 6, 2026 11:55
The chatRoomList is added in the synchronized addChatRoom() so removing of the fields also should be synchronized
Make it similar to getContactItems() that returns a sorted copy.
Remove ContactList.ContactItemComparator as it's the same as the ContactGroup.itemComparator.
Remove sorting of the group.getOfflineContacts() results in the BroadcastDialog()
…ationListeners) since getInvitationListeners() reruns an unmodifiable list
@stokito
Copy link
Contributor Author

stokito commented Jan 6, 2026

I squashed, added the ticet number and rebased on top of master.

@guusdk guusdk merged commit 46d3eb9 into igniterealtime:master Jan 6, 2026
4 checks passed
@stokito stokito deleted the chat_container branch January 6, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants