Skip to content

fix(core): move the Spring beans under modules/ into the scan roots - #6639

Merged
delchev merged 1 commit into
masterfrom
fix/modules-spring-beans-scan-reach
Aug 9, 2026
Merged

fix(core): move the Spring beans under modules/ into the scan roots#6639
delchev merged 1 commit into
masterfrom
fix/modules-spring-beans-scan-reach

Conversation

@delchev

@delchev delchev commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #6635.

Three Spring beans lived under modules/, in packages outside the two roots the platform treats as its
scan convention (org.eclipse.dirigible.components and .engine — the pair DataSourceSystemConfig
uses for @EnableJpaRepositories and dirigible.scan.packages). build/application never noticed,
because DirigibleApplication sits in org.eclipse.dirigible and its default scan covers the whole
tree; any assembly that names its scan packages loses them, silently, because all three are
contributor-shaped.

Bean From To
HanaConnectionEnhancer modules/database/database-sql-hana components/data/data-sources
HanaDatabaseConfigurator modules/database/database-sql-hana components/data/data-sources
ConsoleWebsocketConfig modules/commons/commons-resources components/ide/ide-logs

Plus the vestigial @Component dropped from DirigibleSourceProvider — every consumer constructs it
directly, so the stereotype only advertised an injection point that never existed.

Why these homes

The HANA pair moves next to the injection points that consume it (DirigibleDataSourceFactory,
DataSourceInitializer, both in data-sources). Both classes are package-private, so nothing outside
their package could have referenced them, and the move needs no pom change: data-sources already
depends on core-database (the SPI), api-security (UserFacade) and Hikari, and already carries a
vendor-specific dependency (database-sql-h2), so HANA specifics are not new there.

ConsoleWebsocketConfig joins the four other WebSocketConfigurers — TerminalWebsocketConfig
(ide-terminal), JavaLspWebSocketConfig (ide-java-lsp), JavaDebugWebSocketConfig (ide-java-debug),
DataTransferWebsocketConfig (data-transfer). Every one already lives under components/; the console
one was the only one stranded in modules/. ide-logs takes a dependency on commons-resources for
ConsoleWebsocketHandler.

The appender, handler and log record deliberately stay put: logback configuration names
ConsoleLoggingAppender by fully qualified class name — here in commons-resources/logback.xml and
tests-framework/logback-test.xml, and in downstream configurations we do not control — so moving that
package would silently break them. Only the bean moved.

Why not @AutoConfiguration

The issue offered it as an alternative; it is a trap in this codebase. An auto-configuration class under
org.eclipse.dirigible is itself covered by DirigibleApplication's default scan, so in the full
assembly it would be registered twice — once by the scan, once from the imports file — yielding two
WebSocketConfigurers and a duplicated handler registration on the same path. Moving has no such
ambiguity.

Verification — including the part the issue could only infer

Built the full reactor, started the fat jar, and read the live bean graph from /actuator/beans:

hanaConnectionEnhancer:   registered=True  injected into -> ['dirigibleDataSourceFactory']
hanaDatabaseConfigurator: registered=True  injected into -> ['dataSourceInitializer']
consoleWebsocketConfig:   registered=True  injected into -> ['...DelegatingWebSocketConfiguration']

All three reach exactly the injection points from the issue's table. hanaConnectionEnhancer is loaded
from dirigible-components-data-sources.jar at the new path, confirming the relocation is what is
being wired. The issue marked the two HANA beans "by inspection" for want of a HANA instance — this
demonstrates they reach their intake, though exercising HANA behaviour still needs a HANA server.

Websocket handshake, with controls so the check can actually fail:

/websockets/ide/console        -> 101   (the moved bean)
/websockets/ide/terminal       -> 101   (control: an unmoved sibling)
/websockets/ide/nosuchsocket   -> 404   (control: a path that should not exist)

Zero startup errors, mvn -T 1C clean install -P quick-build green on the whole reactor,
formatter:validate clean on every touched module.

Invariant restored

There is now no Spring bean stereotype anywhere under modules/, which is what the tree is
described by ("pure libraries with no Spring wiring"). The single remaining Spring reference there is
ConsoleWebsocketHandler, which extends TextWebSocketHandler but is not a bean — it is constructed by
the config and called statically by the appender.

Not done

The build guard the issue suggests. A blanket ban on org.springframework under modules/ would not
work — commons-resources legitimately still needs spring-websocket for that handler type — so the
check has to be "no bean stereotypes", which is a source grep rather than an enforcer rule. Happy to add
it as a follow-up if you want it; it seemed worth keeping separate from the fix.

🤖 Generated with Claude Code

Three beans lived under modules/, in packages outside the two roots the platform
treats as its scan convention (org.eclipse.dirigible.components and
.engine - the pair DataSourceSystemConfig uses for @EnableJpaRepositories and
dirigible.scan.packages). build/application never noticed, because
DirigibleApplication sits in org.eclipse.dirigible and its default scan covers
the whole tree; any assembly that NAMES its scan packages loses them.

All three are contributor-shaped, so their absence is silent. A
WebSocketConfigurer that is never registered just means the endpoint 404s; a
List<ConnectionEnhancer> or List<DatabaseConfigurator> injection point just
receives a shorter list. No missing-bean failure, no warning - the context comes
up clean and the capability is quietly gone.

  HanaConnectionEnhancer   -> components/data/data-sources
  HanaDatabaseConfigurator -> components/data/data-sources
  ConsoleWebsocketConfig   -> components/ide/ide-logs

The HANA pair moves next to the injection points that consume it
(DirigibleDataSourceFactory, DataSourceInitializer) and joins its SPI siblings
under components/; both are package-private, so nothing outside their package
could reference them and the move costs no pom change - data-sources already
depends on core-database, api-security and Hikari, and already carries a
vendor-specific dependency (database-sql-h2).

ConsoleWebsocketConfig joins the four other WebSocketConfigurers, every one of
which already lives under components/ (ide-terminal, ide-java-lsp,
ide-java-debug, data-transfer) - it was the only one stranded in modules/.
ide-logs takes a dependency on commons-resources for ConsoleWebsocketHandler.
The appender, handler and record deliberately stay where they are: logback
configuration names ConsoleLoggingAppender by fully qualified class name, in
this repo and in every downstream one, so moving that package would break
configurations we do not control.

Also drops the vestigial @component from DirigibleSourceProvider. Every consumer
constructs it directly, so the stereotype only advertised an injection point
that never existed - and its removal is behaviour-neutral.

No Spring bean stereotype remains anywhere under modules/, which restores the
invariant the tree is described by ("pure libraries with no Spring wiring"). The
one remaining Spring reference there is ConsoleWebsocketHandler, which extends
TextWebSocketHandler but is not a bean - it is constructed by the config and
called statically by the appender.

Registering the beans through an @autoConfiguration was the other option in the
report, and was rejected: an auto-configuration class under
org.eclipse.dirigible is itself covered by DirigibleApplication's default scan,
so in the full assembly it would be registered twice - once by the scan and once
from the imports file - giving two WebSocketConfigurers and a duplicated handler
registration. Moving has no such ambiguity.

Closes #6635

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@delchev
delchev merged commit 41bc48d into master Aug 9, 2026
9 checks passed
@delchev
delchev deleted the fix/modules-spring-beans-scan-reach branch August 9, 2026 14:25
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.

[Core] Spring beans under modules/ sit outside the scan roots and silently disappear in curated assemblies

1 participant