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

Proxy object depending backed by a map will fail when passing through ReplyProducerCleaner#requiresDestruction(Object clean) #3497

Closed
pintomau opened this issue Feb 20, 2021 · 0 comments · Fixed by #3498
Assignees
Milestone

Comments

@pintomau
Copy link

pintomau commented Feb 20, 2021

Hi.

We use proxy beans backed by map of objects for our multi-tenancy solution.

These proxies depend on environment variables being set.

However, since ReplyProducerCleaner#requiresDestruction calls #hashCode on any object, it will force a resolution of the object on the proxy without said environment variable first being set.

In what version(s) of Spring Integration are you seeing this issue?

For example:

5.3.4.RELEASE

Describe the bug

ReplyProducerCleaner#requiresDestruction(Object clean) triggers hashCode of possibly not ready proxy bean.

To Reproduce

Have a proxy bean backed by a map of objects that depend on some environment variable.

Since the mentioned method calls the #hashCode of the proxy bean and the environment variable is not available at the moment the method is called, an exception is thrown.

Expected behavior

One possible solution is so that contains should only be called for the expected bean type of MessageProducer

Sample

https://gist.github.com/crybat/00371f5f7e5e5b521df0a12ad9293706#file-supplierobjectpooldelegate-java

Mitigation

Create a BeanDefinitionRegistryPostProcessor that replaces ReplyProducerCleaner#requiresDestruction with a version that first checks if the provided bean is of MessageProducer type before calling the set's contains method.

https://gist.github.com/crybat/00371f5f7e5e5b521df0a12ad9293706#file-apostprocessor-java

@pintomau pintomau added status: waiting-for-triage The issue need to be evaluated and its future decided type: bug labels Feb 20, 2021
@artembilan artembilan added this to the 5.5 M3 milestone Feb 22, 2021
@artembilan artembilan added in: core backport 5.3.x and removed status: waiting-for-triage The issue need to be evaluated and its future decided labels Feb 22, 2021
@artembilan artembilan self-assigned this Feb 22, 2021
artembilan added a commit to artembilan/spring-integration that referenced this issue Feb 22, 2021
Fixes spring-projects#3497

The `BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS` is filled up
only with the `MessageProducer` instances.
Therefore no reason to calculate a hash code for every single bean passed
to the `ReplyProducerCleaner.requiresDestruction()`

* Check for the `MessageProducer` instance before passing the bean to the
`BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS.contains()`
* Check for the `MessageProducer` in the `ReplyProducerCleaner.postProcessBeforeDestruction()`,
too.
It can be called independently of the `requiresDestruction()` and will calculate a hash code
from the bean again for nothing

**Cherry-pick to 5.4.x & 5.3.x**
garyrussell pushed a commit that referenced this issue Feb 22, 2021
Fixes #3497

The `BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS` is filled up
only with the `MessageProducer` instances.
Therefore no reason to calculate a hash code for every single bean passed
to the `ReplyProducerCleaner.requiresDestruction()`

* Check for the `MessageProducer` instance before passing the bean to the
`BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS.contains()`
* Check for the `MessageProducer` in the `ReplyProducerCleaner.postProcessBeforeDestruction()`,
too.
It can be called independently of the `requiresDestruction()` and will calculate a hash code
from the bean again for nothing

**Cherry-pick to 5.4.x & 5.3.x**
garyrussell pushed a commit that referenced this issue Feb 22, 2021
Fixes #3497

The `BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS` is filled up
only with the `MessageProducer` instances.
Therefore no reason to calculate a hash code for every single bean passed
to the `ReplyProducerCleaner.requiresDestruction()`

* Check for the `MessageProducer` instance before passing the bean to the
`BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS.contains()`
* Check for the `MessageProducer` in the `ReplyProducerCleaner.postProcessBeforeDestruction()`,
too.
It can be called independently of the `requiresDestruction()` and will calculate a hash code
from the bean again for nothing

**Cherry-pick to 5.4.x & 5.3.x**
garyrussell pushed a commit that referenced this issue Feb 22, 2021
Fixes #3497

The `BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS` is filled up
only with the `MessageProducer` instances.
Therefore no reason to calculate a hash code for every single bean passed
to the `ReplyProducerCleaner.requiresDestruction()`

* Check for the `MessageProducer` instance before passing the bean to the
`BaseIntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS.contains()`
* Check for the `MessageProducer` in the `ReplyProducerCleaner.postProcessBeforeDestruction()`,
too.
It can be called independently of the `requiresDestruction()` and will calculate a hash code
from the bean again for nothing

**Cherry-pick to 5.4.x & 5.3.x**
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants