Skip to content

feat: merge packages from multiple @EnableVaadin annotations - #26482

Merged
mcollovati merged 2 commits into
mainfrom
enable-vaadin-merge-scan-packages
Oct 23, 2026
Merged

mcollovati merged 2 commits into
mainfrom
enable-vaadin-merge-scan-packages

Conversation

@mcollovati

Copy link
Copy Markdown
Collaborator

Fixes #25022

new feature · vaadin-spring · Spring apps with @EnableVaadin on
more than one configuration class

Applications can now put @EnableVaadin with packages on several
configuration classes, for example one per module, and Vaadin scans the
packages of all of them. Before, a Spring Boot application failed at
startup with BeanDefinitionOverrideException, and plain Spring kept
only the packages of the last annotation.

Risks:

  • ⚠️ Behaviour change: plain Spring applications with several
    @EnableVaadin annotations now scan all their packages, not only the
    packages of the last annotation processed

  • ✅ No public API, security, memory, serialization, threading,
    performance or migration impact

  • Changed VaadinScanPackagesRegistrar to add the packages of each
    @EnableVaadin to the bean definition that is already registered,
    instead of registering a second one

    • The packages keep their order and duplicates are removed
  • Turned VaadinScanPackages into a package-private record that holds
    an unmodifiable list

  • Documented in EnableVaadin that packages from several annotations
    are merged

  • Added VaadinScanPackagesRegistrarTest, which runs with bean
    definition overriding disabled, as in Spring Boot

  • Based on Make VaadinScanPackages serializable and merge scan packages correctly #25062 by @Hariharan02112004

Fixes #25022

Co-authored-by: Hariharan G <167274701+Hariharan02112004@users.noreply.github.com>
@mcollovati

Copy link
Copy Markdown
Collaborator Author

Type of change

  • Feature
Test coverage
  • VaadinScanPackagesRegistrarTest registers two configuration classes
    with @EnableVaadin and shared packages, with bean definition
    overriding disabled. It fails on main with
    BeanDefinitionOverrideException.
  • The bean's constructor argument is now a List instead of a
    String[]. The vaadin-spring AOT processor tests pass; a native or
    AOT build of a real application was not tried.

@mcollovati mcollovati added the Contribution PRs coming from the community or external to the team label Oct 16, 2026
@mcollovati
mcollovati marked this pull request as ready for review October 16, 2026 08:22

@vaadin-review-bot vaadin-review-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changes — left 1 comment.

Finding
📝 The new javadoc about merging does not say that an annotation without packages contributes nothing and that the default application package is then dropped.

* If packages are not specified then default Spring Boot application
* package is used.
* <p>
* The annotation can be added to several configuration classes. The

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 The new javadoc about merging does not say that an annotation without packages contributes nothing and that the default application package is then dropped.

The two paragraphs now read together as "no packages → default application package" plus "packages of all annotations are scanned". But the merge only covers annotations that declare packages, and getDefaultPackages falls back to the auto-configuration packages only when the merged list is empty.

So a @SpringBootApplication carrying a bare @EnableVaadin next to a module's @EnableVaadin("com.acme.a.views") scans only the module package, and routes in the application package silently stop being found. Worth spelling out, since "one annotation per module" is the pattern this PR promotes.

EnableVaadin.java:76 · documentation

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented in EnableVaadin (efb883d): an annotation without packages adds no packages, and the default application package must be listed explicitly when another annotation declares packages. This was already the behaviour before this PR.

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

 1 665 files  +1   1 750 suites  +1   2h 3m 40s ⏱️ - 4m 14s
12 901 tests +1  12 829 ✅ +1  72 💤 ±0  0 ❌ ±0 
13 534 runs  +1  13 462 ✅ +1  72 💤 ±0  0 ❌ ±0 

Results for commit efb883d. ± Comparison against base commit b234893.

♻️ This comment has been updated with latest results.

@sonarqubecloud

Copy link
Copy Markdown

@mcollovati
mcollovati added this pull request to the merge queue Oct 23, 2026
Merged via the queue into main with commit 417ab14 Oct 23, 2026
93 of 94 checks passed
@mcollovati
mcollovati deleted the enable-vaadin-merge-scan-packages branch October 23, 2026 12:14
vaadin-bot added a commit to vaadin/docs that referenced this pull request Oct 23, 2026
Explain that applying @EnableVaadin to several configuration classes
scans the packages of all of them, on the routing page's guidance for
specifying Vaadin scan packages.

Documents vaadin/flow#26482 (`efb883dc60ec5cb5853c9733800c72b408e5e2e8`).
@github-actions

Copy link
Copy Markdown
Contributor

Pull request created: #6479

Generated by Documentation Bot · agent · 87.5 AIC · ⊞ 11.7K

@github-actions

Copy link
Copy Markdown
Contributor

Documentation Bot: Draft documentation pull request for this change: vaadin/docs#6479

Files updated:

  • articles/flow/integrations/spring/routing.adoc

It was written from the state of this pull request as you see it now. Please review it and mark it ready for review.

Generated by Documentation Bot for #26482 · agent · 87.5 AIC · ⊞ 11.7K · ◷

mcollovati pushed a commit to vaadin/docs that referenced this pull request Oct 23, 2026
Explain that applying @EnableVaadin to several configuration classes
scans the packages of all of them, on the routing page's guidance for
specifying Vaadin scan packages.

Documents vaadin/flow#26482 (`efb883dc60ec5cb5853c9733800c72b408e5e2e8`).
mcollovati pushed a commit to vaadin/docs that referenced this pull request Oct 23, 2026
Documentation for vaadin/flow#26482 by `@mcollovati`.

> [!NOTE]
> The source pull request is merged, so this documentation describes the
final
> shape of the change. Please review it and mark it ready for review.

**Change categories:** BEHAVIOR_CHANGE

| File | Change |
|------|--------|
| articles/flow/integrations/spring/routing.adoc | Note that
`@EnableVaadin` can be added to several configuration classes and that
Vaadin scans the packages of all of them, instead of only describing a
single annotation use. |

Auto-generated by the Documentation Bot — review before merging.

> Generated by [Documentation
Bot](https://github.com/vaadin/flow/actions/runs/39951898666) for #26482
· agent · 87.5 AIC · ⊞ 11.7K ·
[◷](https://github.com/search?q=repo%3Avaadin%2Fdocs+%22gh-aw-workflow-id%3A+doc-bot%22&type=pullrequests)
> - [x] expires <!-- gh-aw-expires: 2026-11-22T12:21:04.621Z --> on Nov
22, 2026, 12:21 PM UTC

<!-- gh-aw-agentic-workflow: Documentation Bot, engine: claude, model:
agent, id: 39951898666, workflow_id: doc-bot, run:
https://github.com/vaadin/flow/actions/runs/39951898666 -->

<!-- gh-aw-expires-type: pull-request -->

<!-- gh-aw-workflow-id: doc-bot -->
<!-- gh-aw-workflow-call-id: vaadin/flow/doc-bot -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Contribution PRs coming from the community or external to the team +0.0.1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow multiple uses of the @EnableVaadin annotation.

3 participants