Problem
Every project scaffolded by dynamia new with a Java/Kotlin/Groovy backend fails to start
(contextLoads test fails, spring-boot:run fails the same way) with:
UnsatisfiedDependencyException: Error creating bean with name 'moduleContainer':
Unsatisfied dependency expressed through field '_providers':
No qualifying bean of type 'java.util.List<tools.dynamia.navigation.ModuleProvider>' available:
expected at least 1 bean which qualifies as autowire candidate.
ModuleContainer (platform/core/navigation/.../ModuleContainer.java) has @Autowired private transient List<ModuleProvider> _providers; (required=true, no default). A minimal app using only
tools.dynamia.app + tools.dynamia.domain.jpa (no other business modules) has zero ModuleProvider
beans of its own, so this is expected to be covered by the fallback in DynamiaBaseConfiguration
(platform/app/.../DynamiaBaseConfiguration.java):
@Bean
@ConditionalOnMissingBean(ModuleProvider.class)
public ModuleProvider emptyModuleProvider() {
return () -> new Module(StringUtils.randomString(), "No modules registered");
}
This fallback is not actually kicking in
Reproduced against the published tools.dynamia:tools.dynamia.app:26.4.1 jar (same version
pinned in cli.properties/the templates), not a stale artifact:
javap -v on the jar confirms emptyModuleProvider() is present, public, correctly annotated
with @Bean and @ConditionalOnMissingBean(ModuleProvider.class) — bytecode is fine.
git merge-base --is-ancestor confirms the commit that introduced it (d8ed4f41, "feat: add empty
ModuleProvider bean for improved module handling") is an ancestor of the 26.4.1 tag, so it should
be included in what's published.
- Yet running the app with
--debug (Spring Boot's ConditionEvaluationReport), DynamiaBaseConfiguration#emptyModuleProvider
never appears in the report at all — not in "Positive matches", not in "Negative matches". Its
sibling @ConditionalOnMissingBean methods in the exact same class (defaultSearchService,
messageService, templateEngine, defaultSearchProvider, noOpCrudService, reportCompiler)
all show up correctly (matched or not). Only emptyModuleProvider is silently absent from condition
evaluation entirely, which points to the bean method never being reached by
ConfigurationClassParser/ConfigurationClassBeanDefinitionReader, not to the condition itself
evaluating false. Root cause of why it's skipped is still open — ideas not yet ruled out:
eager type-resolution during infrastructure bean processing locking the ModuleProvider type before
DynamiaBaseConfiguration's own @Bean methods finish registering, or something specific to how
@Import(RestApiNavigationConfiguration.class) (a plain, non-@Configuration class also imported by
DynamiaBaseConfiguration) interacts with bean method registration order.
Workaround confirmed
Explicitly declaring a ModuleProvider bean in the app (e.g. in the @SpringBootApplication class)
fixes it immediately — List<ModuleProvider> injection is additive, so this doesn't conflict with the
framework's fallback or with real modules added later. Applied as a permanent, documented default in
dynamiatools/template-backend-java (commit 98bd757) and will be mirrored in
template-backend-kotlin/template-backend-groovy.
To reproduce
git clone --depth=1 https://github.com/dynamiatools/template-backend-java
cd template-backend-java
git checkout 0c4fc76 # commit before the workaround was added
./mvnw clean verify # fails: contextLoads
Suggested next step
Someone familiar with DynamiaBaseConfiguration's @Import/@ComponentScan setup and Spring's
ConfigurationClassParser internals should check whether emptyModuleProvider()'s bean method is
even being visited during configuration class parsing (e.g. temporarily add a System.out inside the
method body, or increase to TRACE logging for org.springframework.context.annotation and
org.springframework.boot.autoconfigure.condition) to pin down exactly where it's being dropped, then
decide whether the fix belongs in DynamiaBaseConfiguration itself or in how EnableDynamiaToolsApi
composes its imports.
Problem
Every project scaffolded by
dynamia newwith a Java/Kotlin/Groovy backend fails to start(
contextLoadstest fails,spring-boot:runfails the same way) with:ModuleContainer(platform/core/navigation/.../ModuleContainer.java) has@Autowired private transient List<ModuleProvider> _providers;(required=true, no default). A minimal app using onlytools.dynamia.app+tools.dynamia.domain.jpa(no other business modules) has zeroModuleProviderbeans of its own, so this is expected to be covered by the fallback in
DynamiaBaseConfiguration(
platform/app/.../DynamiaBaseConfiguration.java):This fallback is not actually kicking in
Reproduced against the published
tools.dynamia:tools.dynamia.app:26.4.1jar (same versionpinned in
cli.properties/the templates), not a stale artifact:javap -von the jar confirmsemptyModuleProvider()is present,public, correctly annotatedwith
@Beanand@ConditionalOnMissingBean(ModuleProvider.class)— bytecode is fine.git merge-base --is-ancestorconfirms the commit that introduced it (d8ed4f41, "feat: add emptyModuleProvider bean for improved module handling") is an ancestor of the
26.4.1tag, so it shouldbe included in what's published.
--debug(Spring Boot'sConditionEvaluationReport),DynamiaBaseConfiguration#emptyModuleProvidernever appears in the report at all — not in "Positive matches", not in "Negative matches". Its
sibling
@ConditionalOnMissingBeanmethods in the exact same class (defaultSearchService,messageService,templateEngine,defaultSearchProvider,noOpCrudService,reportCompiler)all show up correctly (matched or not). Only
emptyModuleProvideris silently absent from conditionevaluation entirely, which points to the bean method never being reached by
ConfigurationClassParser/ConfigurationClassBeanDefinitionReader, not to the condition itselfevaluating false. Root cause of why it's skipped is still open — ideas not yet ruled out:
eager type-resolution during infrastructure bean processing locking the
ModuleProvidertype beforeDynamiaBaseConfiguration's own@Beanmethods finish registering, or something specific to how@Import(RestApiNavigationConfiguration.class)(a plain, non-@Configurationclass also imported byDynamiaBaseConfiguration) interacts with bean method registration order.Workaround confirmed
Explicitly declaring a
ModuleProviderbean in the app (e.g. in the@SpringBootApplicationclass)fixes it immediately —
List<ModuleProvider>injection is additive, so this doesn't conflict with theframework's fallback or with real modules added later. Applied as a permanent, documented default in
dynamiatools/template-backend-java(commit 98bd757) and will be mirrored intemplate-backend-kotlin/template-backend-groovy.To reproduce
Suggested next step
Someone familiar with
DynamiaBaseConfiguration's@Import/@ComponentScansetup and Spring'sConfigurationClassParserinternals should check whetheremptyModuleProvider()'s bean method iseven being visited during configuration class parsing (e.g. temporarily add a
System.outinside themethod body, or increase to
TRACElogging fororg.springframework.context.annotationandorg.springframework.boot.autoconfigure.condition) to pin down exactly where it's being dropped, thendecide whether the fix belongs in
DynamiaBaseConfigurationitself or in howEnableDynamiaToolsApicomposes its imports.