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

IndexOutOfBoundsException in DirectMessageListenerContainer#adjustConsumers #703

Closed
davidbilge opened this issue Jan 17, 2018 · 4 comments
Closed
Assignees

Comments

@davidbilge
Copy link
Contributor

Our system that uses spring-amqp constantly logs this stacktrace:

java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
        at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
        at java.util.LinkedList.remove(LinkedList.java:525)
        at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer.adjustConsumers(DirectMessageListenerContainer.java:289)
        at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer.setConsumersPerQueue(DirectMessageListenerContainer.java:152)
        at org.springframework.amqp.rabbit.listener.DirectReplyToMessageListenerContainer.processMonitorTask(DirectReplyToMessageListenerContainer.java:136)
        at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer.lambda$actualStart$3(DirectMessageListenerContainer.java:429)
        at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

Looking at the adjustConsumers method in DirectMessageListenerContainer it seems like this will always happen if newCount < consumerList.size() - 1, i.e. if the number of consumers is to be reduced by more than one.

One solution might be to replace

SimpleConsumer consumer = consumerList.remove(i);

with

SimpleConsumer consumer = consumerList.remove(0);

if it does not matter which consumers will be removed.

This affects spring-rabbit 2.0.1.RELEASE.

@artembilan
Copy link
Member

Ha! Sure! That's definitely good catch 😄

Indeed, when we call consumerList.remove(8) on the list of 10, the list becomes as 9 of the size. So, the next consumerList.remove(9) brings us exactly that IndexOutOfBoundsException.

I have just modified DirectMessageListenerContainerIntegrationTests.testAddRemoveConsumers() to adjust from 4 to 1 consumer and get exactly the same exception:

java.lang.IndexOutOfBoundsException: Index: 3, Size: 2

	at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
	at java.util.LinkedList.remove(LinkedList.java:525)
	at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer.adjustConsumers(DirectMessageListenerContainer.java:289)
	at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer.setConsumersPerQueue(DirectMessageListenerContainer.java:152)
	at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainerIntegrationTests.testAddRemoveConsumers(DirectMessageListenerContainerIntegrationTests.java:296)

@artembilan artembilan self-assigned this Jan 17, 2018
artembilan added a commit to artembilan/spring-amqp that referenced this issue Jan 17, 2018
Fixes spring-projects#703

When we adjust consumers down by more than 1 instance we end up with the
`IndexOutOfBoundsException` because we perform removal by the
calculated index.

* Change algorithm to remove only from `0` index.
In the end it doesn't matter which consumers remain in the container
garyrussell pushed a commit that referenced this issue Jan 17, 2018
Fixes #703

When we adjust consumers down by more than 1 instance we end up with the
`IndexOutOfBoundsException` because we perform removal by the
calculated index.

* Change algorithm to remove only from `0` index.
In the end it doesn't matter which consumers remain in the container
@davidbilge
Copy link
Contributor Author

Are there any plans on the next bugfix release? Thinking about using a patched jar for our system but it would be nice to be able to avoid this.

@garyrussell
Copy link
Contributor

It's currently scheduled for next Wednesday; just in time for the Boot 2.0 release candidate 1. We could possibly pull it forward a day or two if necessary.

@davidbilge
Copy link
Contributor Author

Next wednesday sounds good to me. Thanks for the information!

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

No branches or pull requests

3 participants