Skip to content

Conversation

@Jarvx
Copy link

@Jarvx Jarvx commented Oct 21, 2025

Issue: #11758

Bug description

The bug occurs because replacement beans (@Replaces) are only discovered among the candidate collection being considered, not across the global registry. As a result, replacements declared elsewhere in the registry (e.g., a non-@Context replacement for a @Context bean) can be missed, and already-cached singleton instances for the replaced bean can remain in singleton caches, leading to nondeterministic behavior.

Solution / fix

The test defines an @Context-scoped bean (OriginalContextApi) and a @Singleton replacement (ReplacementSingletonApi) annotated with @Replaces(OriginalContextApi). It asserts that after starting the ApplicationContext, the original @Context bean is not instantiated and that injecting ReplacedApi yields the replacement. On the original code, the test fails because the original @Context bean is eagerly created, reproducing the reported issue where replacing a @Context bean with a non-@context bean still instantiates the original. This is aligned with the issue description. 2)

Patch effectiveness: The patch makes two key changes. In DefaultBeanContext, it scans all bean definitions for replacements and prunes any eager (@Context) beans from eagerInit if they are replaced, regardless of the replacement's scope. This ensures the original @context bean is not eagerly created when there is any replacement, even if the replacement is not @Context. In SingletonScope, it removes the fallback from findBeanRegistrationByExactDefinition to the type/qualifier-based cache, preventing returning a previously created instance of a different bean definition. This addresses the nondeterministic case where an original singleton could be returned because it matched by type/qualifier. Together, these changes fix both parts of the issue: preventing unwanted eager instantiation and ensuring correct bean selection by exact definition.

Steps to reproduce

./gradlew :test-suite-kotlin-ksp:test

@Jarvx
Copy link
Author

Jarvx commented Oct 24, 2025

I'll close this pr first because the CI fails.

@Jarvx Jarvx closed this Oct 24, 2025
@Jarvx Jarvx changed the title Fix 11758: Ensure @Replaces beans are detected globally [Gen AI] Fix 11758: Ensure @Replaces beans are detected globally Oct 24, 2025
@Jarvx Jarvx reopened this Oct 24, 2025
@dstepanov
Copy link
Contributor

For the core functionality always add tests for Java. (Not Kotlin like in this PR, nor Groovy). In this case the test should go to inject-java module.

@dstepanov
Copy link
Contributor

I don't understand why do you need to scan all the classes. The method has candidates all the possible candidates for this injection.

@Jarvx
Copy link
Author

Jarvx commented Nov 1, 2025

This PR is improved by a new test script and a new patch. Hope you find it useful.

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.

2 participants