Fix cross-module @ComponentScan hints generation without @Configuration#25
Open
wjz2001 wants to merge 2 commits intoInsertKoinIO:mainfrom
Open
Fix cross-module @ComponentScan hints generation without @Configuration#25wjz2001 wants to merge 2 commits intoInsertKoinIO:mainfrom
wjz2001 wants to merge 2 commits intoInsertKoinIO:mainfrom
Conversation
…version to subprojects only.
…to match documented behavior and fix cross-module compileSafety resolution.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes a cross-module failure mode in the Koin Compiler Plugin where
compileSafety(call-site validation) reports Missing definition for dependencies that are actually defined in a library module using@Module + @ComponentScan, unless the module is also annotated with@Configuration. The fix aligns the plugin’s behavior with the documented usage of@ComponentScanon plain@Moduleclasses and prevents a “hint black hole” that breaks downstream visibility.Problem Statement
In a multi-module Gradle build, a library module may declare a Koin module using annotations:
and define components in the scanned packages:
A consuming app module may inject those types:
When
compileSafety = trueis enabled, the consumer compilation can fail with errors similar to:[Koin] Missing definition: com.example.lib.Reporesolved by: inject<Repo>()No matching definition found in any declared moduleeven though the definition exists and is properly annotated.
Root Cause Analysis (Why it happens)
This failure is caused by an interaction between two hint-generation paths and their exclusion conditions:
“Orphan definition” hints (e.g.,
definition_*,definitionfunc_*) are generated only for definitions that are not “covered” by a local@ComponentScan.@ComponentScan, it may be excluded from orphan hint generation (by design, to avoid redundancy).Module-scoped
@ComponentScanhints (e.g.,componentscan_*,componentscanfunc_*) are intended to export what a module’s scan discovered so that downstream compilations can resolve scanned definitions across Gradle modules.However, the existing implementation only generates module-scoped scan hints for modules that satisfy:
@Module + @ComponentScan + @ConfigurationIf a module has
@Module + @ComponentScanbut does not have@Configuration, then:@Configuration).This produces a “black hole” where the provider JAR contains no usable hints under
org/koin/plugin/hintsfor those scanned definitions, so downstreamcompileSafetyvalidation cannot “see” them and fails.This was verified empirically by inspecting the provider artifact:
@Configuration,jar tf <provider>.jarshowed noorg/koin/plugin/hintsentries.@Configuration, the JAR containedorg/koin/plugin/hints/...Koin_hints_...classes and the Missing definition errors disappeared.Why This PR Is Correct / Alignment With Documentation
The documented behavior of Koin annotations shows
@ComponentScanbeing used directly on@Moduleclasses;@Configurationis described as a grouping/selection concept, not as a prerequisite for component scanning or cross-module discovery.Therefore, requiring
@Configurationfor module-scoped scan hint generation is inconsistent with the expected usage pattern and causes valid projects to fail compilation undercompileSafety.What This PR Changes
Behavioral change: module-scoped scan hints are generated for all
@Moduleclasses that have@ComponentScan, not only for modules that also have@Configuration.Concretely, in
KoinAnnotationProcessor.generateModuleScanHints(...), the module selection changes from:@Configuration + @ComponentScanmodules”to:
@ComponentScanmodules”@Configurationis still recognized and can be logged/observed, but it no longer gates scan hint generation.Reproduction Steps (Minimal Example)
Create a library module
:libwith:In the scanned package:
In an app module
:appthat depends on:lib, enable:koinCompiler { compileSafety = true }and inject:
Build the app:
Repo.org/koin/plugin/hints.Verification / Evidence
io.insert-koin:koin-compiler-plugin -> project ...).jar tf) was used to confirm presence/absence oforg/koin/plugin/hintsentries.clean,--rerun-tasks,--no-build-cache) was used to avoid incremental compilation artifacts during validation.Impact and Trade-offs
Pros
compileSafetyvisibility for valid@Module + @ComponentScanmodules without requiring@Configuration.@ComponentScan.Potential trade-offs
compileSafetyvalidation as previously hidden definitions become visible.Notes
@Configurationremains useful for grouping/conditional module loading but should not be required to export scan results across modules.@Configurationand non-@Configurationscan modules) to prevent regressions.