Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check hasNext when looking for ordered UserDestinationResult sessionIds #34333

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

brandenclark
Copy link

@brandenclark brandenclark commented Jan 29, 2025

Found a bug in UserDestinationMessageHandler.SendHelper#send that occurs when the UserDestinationResult was created by the pre-6.1.x constructor. Bug was introduced with 3277b0d

Ideally this fix will target 6.1+ and should be compatible. Not sure if there's a special way to call that out as a first-time contributor.

Changes

  • Add a test that reproduces the error and subsequently covers the fix
  • Check if the iterator has a next value before accessing it and use the default condition if it does not
    • Using the default seems to be the original intent and was just missing this initial check

Bug Details

The UserDestinationMessageHandler unsafely retrieves values from an iterator of sessionId strings to lookup ordered messages.

This happens when the UserDestinationResult used to route the message was created with the pre-6.1.x constructor this retrieval throws a NoSuchElementException.

This is because the older constructor passes a null to the newer constructor for the sessionIds constructor arg. The class attempts to safe handle this null arg by creating an EmptySet that eventually provides an [EmptyIterator],(https://github.com/openjdk/jdk/blob/98a93e115137a305aed6b7dbf1d4a7d5906fe77c/src/java.base/share/classes/java/util/Collections.java#L4559) which then throws for Set#next.

This bug seems to only happen for custom implementations of UserDestinationResolver as the DefaultUserDestinationResolver always provides a populated set to the new constructor.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 29, 2025
@sbrannen sbrannen added the in: messaging Issues in messaging modules (jms, messaging) label Jan 29, 2025
@sbrannen sbrannen requested a review from rstoyanchev January 29, 2025 15:09
@@ -280,7 +280,7 @@ public void send(UserDestinationResult destinationResult, Message<?> message) th
Iterator<String> itr = (sessionIds != null ? sessionIds.iterator() : null);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, sessionIds coming from destinationResult.getSessionIds() is documented to be nullable, but actually the sessionIds are final and instantiated to always be non-null. That method could be annotated @nonnull and the logic here would be simpler. sessionIds doesn't have to be checked for null in this line, and therefore itr is never null and doesn't need to be check for null in line 283.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! I'll make that change just so it's up for viewing and we can get some feedback from @rstoyanchev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: messaging Issues in messaging modules (jms, messaging) status: waiting-for-triage An issue we've not yet triaged or decided on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants