chore: import vaadin-cdi as a Flow module and run its tests in validation - #25525
chore: import vaadin-cdi as a Flow module and run its tests in validation#25525totally-not-ai[bot] wants to merge 632 commits into
Conversation
This reverts commit 389d7df. Change-Id: I162012949b0b92e8388d997752436d28329e3b13
Change-Id: I5b7d9907e7f3464f1930611abf0d1a0184fa7d1a
Change-Id: I0f9721163cb105774fabfae5f0af31033e3506da
Change-Id: I6089f881b05b9bb6869898cce12efafc244b02c7
Change-Id: Ia260dd68b76c90060e2b64a8f3da384022636ef1
Change-Id: I2eec19c14cef6b62b6063bffcc305ea984322330
Change-Id: I2ef8dc42d7238e9784f443f6e1190249f82bcfd1
Change-Id: I127245eaf3ab05877a4b4bbf7e95bbe4bbf349f3
Change-Id: Ibaa778a2665e677427cefca4bdc15c6987724cae
Change-Id: I718308184ec7be64d336ea95c1d2684254649a55
Change-Id: I2be7e557843eaa7c7fc53df15759752b71975a95
Change-Id: If457da33cf5489c9b5cd552827fb60166599cd72
Change-Id: I326af890640a1b3e5fc8d96a2b3407b19785fc95
Using a nested VaadinCDIServlet is allowed. Change-Id: I17261000feef668c7bd48b521eca3e3cf0a531f7
Change-Id: Ice24d701df7d3e0765c1493e1e75af69e7f54666
Change-Id: I17dfa70e98e64ea99bf897c48bdae7aad97a0f9d
Change-Id: Ic8199751125db735968297ae45b9a181c28d0313
Change-Id: Ic4fea717afa7389a17f82c2adf664f62f8198627
Change-Id: I37da96e890363029eddeaf76575100f237db2e21
Change-Id: Ic316f0fcfbbeebf96f5b33c6f34dc9e6fbe48d73
Change-Id: I04e4171168c021da9e690f553b1ff9c70412fdf9
Change-Id: I48f4623c9379c3a2bef11eda5601ace5458de644
Change-Id: Ibbcd930a52675ea1983ab38c027692a6f6758144
Change-Id: I3044360d37d69916e8a8c861539293681d9a5520
Change-Id: I5831d94061fa9070e5c740d742d2df0e905c3288
Change-Id: Id596cd1f38df95796905b057fd3d2818f84427d0
Change-Id: If5c8b606365247a74637174e1c49d49fc9ed510f
Change-Id: Ib5ca7086840fdd6320550522a6cfee504883a861
Change-Id: If4cac244c171bfb292c29f68dabafa54587edc55
WildFly 39 ships with Jackson 2.20 which is compatible with Vaadin 25, so the Jackson module exclusion workaround is no longer needed. The workaround is preserved but commented, as a reminder for potential future similar issues.
) Accessing `@VaadinSessionScoped` beans from background threads that have a `VaadinSession` set as current but don't hold the session lock causes an `IllegalStateException` from `VaadinSession.getAttribute()`. Check `hasLock()` in `isActive()` so the scope correctly reports as inactive without the lock, producing the expected `ContextNotActiveException` instead. Fixes #495
Configure the spotless plugin with settings matching Vaadin Flow: - Add VaadinJavaConventions.xml for Eclipse formatter settings - Add cdi.importorder for import ordering - Add apache2-license-header.txt for license headers - Configure Java formatting with forbidden wildcard imports - Configure POM sorting This resolves #509. https://claude.ai/code/session_01S7HsGqoR2cKkfdpxzYGqnW Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Marco Collovati <marco@vaadin.com>
Fork PRs will have the `build` job run (compile, matrix generation) but no tests. Reviewers must validate fork PRs manually by checking out the branch.
…#515) Move the activation predicate and storage-access logic out of `VaadinSessionScopedContext` into a nested `ContextualStorageManager` managed bean. The context becomes a thin delegator. As a side effect, applications may replace the bean via CDI `@Specializes` to adjust behavior — though the manager is intentionally undocumented and overriding it is at the integrator's own risk. Adds integration tests covering the strict default and the lenient `@Specializes` scenario from a background thread that does not hold the session lock. References #506
) * fix: bind route scope to window name only for `@PreserveOnRefresh` Route scope storage was keyed by window name whenever the extended client details reported one. That check used to be an implicit `@PreserveOnRefresh` detector: up to Vaadin 24, Flow requested the window name only for preserved navigation chains. Since #22719 the client details are collected during UI initialization and every tab gets a window name, so the check is always true. All `@RouteScoped` beans became shared between the UIs of the same browser window. When two such UIs are alive at the same time (duplicated tab, restored session, or reloads faster than the unload beacons that close the previous UI), the second UI is given a route target that still belongs to the first UI's state tree, and navigation fails with "Can't move a node from one state tree to another". The storage is now bound to the window only when the navigation target or one of its layouts is annotated with `@PreserveOnRefresh`, mirroring Flow's isPreserveOnRefreshTarget rule. Otherwise it is bound to a single UI and destroyed on its detach. Fixes #526 * fix: keep route scope storage when its owner changes scope The storage key of an owner switches between window and UI binding when navigating between a preserved and a plain child of the same layout. The storage is now relocated to the new key instead of letting a second one be created, so the beans of a layout that stays in the navigation chain are not recreated. Taking over the window storage is skipped while another UI of the same window is still alive. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Flow 25.3 (#25268) moved the service listeners onto the new VaadinServiceEventBus. BootstrapHandler now fires a UIInitEvent through the bus instead of calling VaadinService.fireUIInitListeners, which is deprecated for removal and no longer invoked by Flow. The extension attached its CDI event forwarding listeners to the UI from an override of that method, so they were never registered: no navigation, poll or UI detach event reached CDI observers, and @RouteScoped beans got no context because RouteScopedContext observes BeforeEnterEvent and AfterNavigationEvent. UIEventListener now implements UIInitListener and attaches itself to the UI before firing the CDI UIInitEvent, and is registered with addUIInitListener instead of a lambda. Only APIs available since Flow 1.0 are used, so the fix works on both Flow 25.2 and 25.3. The unit tests fire the event the way Flow does, through the service event bus, reached reflectively so that they still compile and exercise the same code path against Flow 25.2, where the bus does not exist yet.
Brings vaadin/cdi main into this repository the same way vaadin/spring was imported in #13002: a merge of the upstream history so `git log` and `git blame` keep working for the CDI sources. The library lands at /vaadin-cdi and the Arquillian integration tests at /flow-tests/vaadin-cdi-tests. The dead vaadin-cdi-example module (a README with no sources) and the IDE descriptors are left behind; the upstream root pom, CI workflow and formatter configuration are replaced by Flow's in the following commits.
Reparents vaadin-cdi to flow-project so it inherits the Flow version and
is released with it: the flow-* dependencies now resolve through
${project.version} instead of a separately maintained
vaadin.flow.version, and vaadin-cdi is published through flow-bom.
The Jakarta EE BOM was already imported by the Flow parent at the same
11.0.0 version the CDI parent used, so only the Weld versions had to be
hoisted. The source, surefire and javadoc plugin configuration is
dropped in favour of the Flow parent's.
BeanManagerProvider switches to SLF4J, which the check-logging-imports
enforcer rule requires of every module in this repository.
Reparents the imported Arquillian suite to flow-tests, which already supplies flow-client, flow-html-components, flow-test-util, junit and the prerelease repositories, so those declarations and the separate flow-maven-plugin version can go. The Arquillian and ShrinkWrap versions stay module-local, the way vaadin-spring-tests keeps its Spring ones. Every test here deploys to a real application server, so surefire now skips unless one of the container profiles is active. Without that guard the module would fail a plain `mvn verify` over flow-tests, since the tests are surefire-bound `*Test` classes rather than failsafe ITs.
Runs spotless:apply with Flow's configuration. The Eclipse formatter profile and license header are byte-identical to the ones the CDI repo used, so the Java churn is limited to what the newer spotless version reflows; the Polymer test template is reformatted because Flow also runs prettier over frontend sources.
The suite deploys to a real application server, which the generated it-tests matrix has no way to express, so computeMatrix.js excludes the module and validation.yml gets a job of its own with the five container profiles the CDI repository used. Running all five on every Flow change would add a ~30 minute tail to validation, so only tomee runs unconditionally, as a smoke test for changes anywhere in Flow; wildfly, payara, liberty and tomcat-weld run when the CDI sources themselves change, gated the same way the gradle-tests job gates its expensive steps.
Adds the module to the maps in CLAUDE.md and guidelines/repository.md, repoints the README links that referred to paths in the vaadin/cdi repository, and records in the test module's README how to select a container profile — the upstream root README carried those instructions and it was not imported.
The `Run CDI ITs` step piped Maven through tee, so the step exited with tee's status and every container failure reported success. It now uses the detached stdio the it-tests job uses, which also keeps an application server JVM that outlives Maven from pinning the step open by holding the pipe. cdi-tests restores saved-workspace, so cleanup-artifacts has to wait for it before deleting the artifact, and test-results now waits for it too: without that a failing container leg did not flip the aggregate check and whether the CDI surefire reports made it into the published test report was down to timing. Adds a step that builds the module with no container profile and asserts the tests are skipped rather than run or failed. That is the one path this branch introduced that nothing covered, since `mvn install -DskipTests` leaves the module out and every leg passes -P<container>. The slow test profile is renamed to slow-tests to match the id the rest of the repository uses, and the README now shows it being combined with a container profile - on its own it skips everything.
|
|
Every test in the module failed at its @deployment method with "Non-parseable POM .../effective-pom.xml". ShrinkWrap builds the WAR by reading that file with a strict POM parser, and what help:effective-pom writes under the Flow parent is not well-formed XML, for two independent reasons: - the plugin's banner contributes an XML declaration and the model it renders contributes a second one, which the parser rejects as a "PITarget with reserved xml name". Which rendering path the plugin takes depends on the model, which is why this appeared only after the module was reparented. - build-helper:parse-version, which the Flow parent runs and the CDI parent did not, sets a property whose name ends in a question mark. That is a legal Maven property name but not a legal XML element name, so Maven serialises a tag no parser accepts. An antrun execution now strips both and validates what is left, so a future change of shape fails on the spot instead of resurfacing as every test failing to build its archive. Neither the declaration nor the parsedVersion properties are of any use to ShrinkWrap, which reads this file for the dependency list. Verified by driving ArchiveProvider directly: the smoke deployment resolves and packages its 19 libraries again.
The liberty leg failed the DependencyConvergence rule the Flow parent enforces and the CDI parent did not: the Liberty adapter pulls the Arquillian core in at 1.7.0.Final, diverging from what arquillian-junit-container brings, across nine artifacts. Importing arquillian-bom in place of the single managed entry pins all of them. Nearest-wins already resolved them to arquillian.version, so this records the version that was in effect rather than changing it, and it holds for every container profile instead of only the ones that happen not to declare an adapter of their own. Convergence now passes for tomee, wildfly, payara, liberty and tomcat-weld alike.
Declaring maven-antrun-plugin also activated the execution the flow-tests parent manages, which deletes an exploded WAR's WEB-INF/lib. This module is a jar and ShrinkWrap assembles its archives in process, so that directory never exists and the execution printed an Ant BuildException and a stack trace on every run - non-fatal, but indistinguishable from a real failure in the log. Bound to phase none here. The dependencyConvergence rule lives in the enforcer default-cli execution, so no lifecycle phase evaluates it and nothing in CI would have caught the Arquillian divergence the previous commit fixed, or a regression of it. The CDI job now names the goal explicitly, which evaluates it once per container profile - the profiles are what bring the conflicting adapters. Confirmed it fails again if the BOM import is removed.
|
|
@claude do you see any blockers in this move - any concerns about CI, release, structure problems, test run and similar? |
|
Claude finished @mshabarov's task in 2m 19s —— View job Review: blockers & concerns for the CDI importI read the CI wiring ( 🔴 Likely merge blockers (checks, not code)
🟠 Release / versioning — worth confirming before merge
🟡 CI cost / robustness — by design, but note the trade‑offs
🟢 Things I checked that are fine
One small nit (non‑blocking)
Bottom lineNo structural blocker to the move itself — the build/reactor/CI plumbing is sound. The two things that will actually gate the merge are external to the code: the Sonar quality gate (coverage + reliability on new code) and the CLA. The one decision I'd want made explicitly is the release coordination (old Analysis based on the branch as of |




Brings the
vaadin/cdirepository into Flow as a first-class module, so the CDI integration is built, versioned and tested together with the rest of Flow instead of tracking it from a separate repository.What changed
Module layout
vaadin-cdiis imported with its full git history and added to the root reactor and toflow-bom, so it releases with Flow's version number.flow-tests/vaadin-cdi-tests. Theflow-testsparent already suppliesflow-client,flow-html-components,flow-test-util, JUnit and the prerelease repositories, so those declarations and the module's ownflow-maven-pluginversion are gone; Arquillian and ShrinkWrap versions stay module-local the wayvaadin-spring-testskeeps its Spring ones.cdi.container.tests.skipunless one of the container profiles (tomee,wildfly,payara,liberty,tomcat-weld) is active — otherwise a plainmvn verifyoverflow-testswould fail.weld-se-core/weld-junit5versions for the module's unit tests.CI
computeMatrix.jsexcludesflow-tests/vaadin-cdi-tests— the generatedit-testsmatrix has no way to express "deploy to an application server" — andvalidation.ymlgets a dedicatedcdi-testsjob with the five container profiles.tomeeruns unconditionally as a smoke test; the other four run when the CDI sources themselves change, gated the same waygradle-testsgates its expensive steps (and running everything when there is no base to diff against).test-resultsandcleanup-artifactsnow depend oncdi-tests, so a failing container leg flips the aggregate check and the CDI surefire reports reliably reach the published report instead of racing artifact deletion.Run CDI ITsstep uses the detached stdio theit-testsjob uses rather than piping throughtee: piping made the step exit withtee's status (so every container failure reported success), and an application server JVM outliving Maven could pin the step open by holding the pipe.Build problems found while wiring it up
target/effective-pom.xmlwith a strict POM parser, and whathelp:effective-pomwrites under the Flow parent is not well-formed XML: the plugin's banner contributes one XML declaration and the rendered model a second (rejected as a "PITarget with reserved xml name"), andbuild-helper:parse-version— which the Flow parent runs and the CDI parent did not — sets a property whose name ends in?, which Maven serialises as an illegal XML element name. An antrun execution strips both and then runsxmlvalidate, so a future change of shape fails on the spot instead of resurfacing as every test failing at its@Deploymentmethod.DependencyConvergencerule the Flow parent enforces: the Liberty adapter pulls Arquillian core in at1.7.0.Final, diverging fromarquillian-junit-containeracross nine artifacts. Importingarquillian-bomin place of the single managed entry pins all of them at the version nearest-wins already resolved, for every container profile.maven-antrun-pluginalso activated thedelete-lib-folderexecution theflow-testsparent manages, which deletes an exploded WAR'sWEB-INF/lib. This module is a jar and ShrinkWrap assembles archives in process, so that directory never exists and the execution printed an AntBuildExceptionand a stack trace on every run — non-fatal, but indistinguishable from a real failure. Bound to phasenonehere.dependencyConvergencerule lives in the enforcerdefault-cliexecution, so no lifecycle phase evaluates it and nothing in CI would have caught the divergence above or a regression of it. The CDI job namesenforcer:enforceexplicitly, which evaluates it once per container profile — the profiles are what bring the conflicting adapters.slow-teststo match the id the rest of the repository uses.Docs
vaadin-cdiadded to the module maps inCLAUDE.mdandguidelines/repository.md.vaadin-cdi/README.mdlinks repointed fromvaadin/cdipaths to in-repo paths.flow-tests/vaadin-cdi-tests/README.mdrecords how to select a container profile and how to combineslow-testswith one — the upstream root README carried those instructions and was not imported.API Changes
Nothing here is new to application developers: these are the same types that ship today in the separately released
com.vaadin:vaadin-cdiartifact, and they now appear as additions only because the module moved into this repository. No public or protected declaration changed during the import — the commits after the history import touch only a private logger field and formatting.32 top-level public types added (plus 5 public nested types), no removals, no signature changes. Package-private types (
BeanLookup,DeploymentValidator,VaadinTaskExecutorSelector,AbstractContextualStorageManager) and the test fixtures underflow-tests/vaadin-cdi-tests/src/main/javaare not API and are omitted.com.vaadin.cdi.AbstractCdiInstantiator
com.vaadin.cdi.CdiInstantiator
com.vaadin.cdi.CdiInstantiatorFactory
com.vaadin.cdi.CdiServletDeployer
com.vaadin.cdi.CdiVaadinServlet
com.vaadin.cdi.CdiVaadinServletService
com.vaadin.cdi.CdiVaadinServletService.CdiVaadinServiceDelegate
com.vaadin.cdi.UIDetachEvent
com.vaadin.cdi.VaadinExtension
com.vaadin.cdi.annotation.CdiComponent
com.vaadin.cdi.annotation.NormalRouteScoped
com.vaadin.cdi.annotation.NormalUIScoped
com.vaadin.cdi.annotation.RouteScoped
com.vaadin.cdi.annotation.RouteScopeOwner
com.vaadin.cdi.annotation.UIScoped
com.vaadin.cdi.annotation.VaadinServiceEnabled
com.vaadin.cdi.annotation.VaadinServiceScoped
com.vaadin.cdi.annotation.VaadinSessionScoped
com.vaadin.cdi.context.ContextWrapper
com.vaadin.cdi.context.RouteScopedContext
com.vaadin.cdi.context.RouteScopedContext.ContextualStorageManager
com.vaadin.cdi.context.UIScopedContext
com.vaadin.cdi.context.UIScopedContext.ContextualStorageManager
com.vaadin.cdi.context.VaadinServiceScopedContext
com.vaadin.cdi.context.VaadinServiceScopedContext.ContextualStorageManager
com.vaadin.cdi.context.VaadinSessionScopedContext
com.vaadin.cdi.context.VaadinSessionScopedContext.ContextualStorageManager
com.vaadin.cdi.util.AbstractContext
com.vaadin.cdi.util.AnyLiteral
com.vaadin.cdi.util.BeanManagerProvider
com.vaadin.cdi.util.BeanProvider
com.vaadin.cdi.util.ClassUtils
com.vaadin.cdi.util.ContextUtils
com.vaadin.cdi.util.ContextualInstanceInfo
com.vaadin.cdi.util.ContextualStorage
com.vaadin.cdi.util.DependentProvider
com.vaadin.cdi.util.ProxyUtils
Test summary
No test methods were authored on this branch: the two suites arrive wholesale with the import (67 Weld unit tests in
vaadin-cdi, 58 Arquillian ITs inflow-tests/vaadin-cdi-tests), and the only post-import edits to test sources are two formatting reflows. What this change has to prove is therefore that those suites still run, and that the build/CI plumbing added around them behaves — so the rows below are the behaviours of the wiring, and the mapping names the suites and build assertions that pin them at class granularity rather than listing 125 imported method names.999.99-SNAPSHOTunit-teststomee) and scopes, push, i18n, templates and service customisation work end to end — on every Flow changetomeeis ungatedwildfly,payara,libertyandtomcat-weld— but only whenvaadin-cdi/,flow-tests/vaadin-cdi-tests/orvalidation.ymlchangedcdi.container.tests.skipis reached by no other job (mvn install -DskipTestsleaves the module out, every matrix leg passes-P<container>), so without this a regression would only surface in a contributor's localmvn verifytarget/effective-pom.xmlis well-formed XML after sanitisation@Deploymentmethod with an opaque "Non-parseable POM", which is exactly how this was founddefault-cli, so without naming the goal nothing evaluates it and the liberty divergence would silently returnRun CDI ITsstep exits non-zero when Maven fails, and a failing leg flips thetest-resultsaggregate checktee's exit status; the fix is verified only by inspection and by the first genuinely red runcomputeMatrix.jsexcludesflow-tests/vaadin-cdi-testsfrom the generatedit-testsmatrixscripts/has no test harness to assert thisMapping — tests and build-time assertions on this branch to the rows above:
CdiInstantiatorTest.getI18NProvider_beanEnabled_instanceReturned,.getMenuAccessControl_beanEnabled_instanceReturned,.getPageTitleGenerator_beanEnabled_instanceReturned,.getServiceInitListeners_javaSPIListenerExists_containsJavaSPIListener(+ rest of class),CdiInstantiatorDefaultsTest.*→ 1CdiVaadinServletServiceTest.getInstantiator_serviceInitialized_cdiInstantiatorReturned,.init_instantiatorAmbiguous_ExceptionThrown,.init_instantiatorUnsatisfied_ExceptionThrown,.init_instantiatorInitReturnsFalse_ExceptionThrown(+ rest of class; reflowed on this branch),CdiVaadinServletTest.*,CdiVaadinServletServiceExecutorTest.*,PolymerTest.*→ 1DeploymentValidatorTest.validate_normalScopedProblems_collected,.validate_routeScopedProblems_collected→ 1SessionContextTest.get_sessionExistsButNotLocked_contextNotActive,.defaultManager_sessionLocked_isActive,.context_nullSession_notActive,.defaultManager_storageAccess_returnsStorage,ServiceContextTest.*,UiContextNormalTest.*,UiContextPseudoTest.*,RouteContextNormalTest.*,RouteContextPseudoTest.*→ 1RouteContextualStorageManagerTest.onBeforeEnter_initialNavigationTarget_scopeDoesNotExist_Throws,.afterNavigation_initialNavigationTarget_scopeDoesNotExist_Throws,.onBeforeEnter_group1Navigation_beansAreScoped,.onBeforeEnter_group2NavigationAfterGroup1_beansAreDestroyed(+ rest of class; reflowed on this branch) → 1SmokeTest.injectionHappensWithEnabledCdiServlet,.injectionDoesNotHappenWithDisabledCdiServlet,.navigationCorrectlyHandlesProxiedViews→ 2, 3, 5RouteContextTest.navigateFromRootToMasterReleasesRootInjectsEmptyBeans,.navigationFromAssignedToMasterHoldsGroup,.navigationFromApartToMasterReleasesGroup,.rerouteReleasesSource(+ rest),UIContextTest.*,SessionContextTest.*,SessionContextStrictTest.*,SessionContextSpecializesTest.*→ 2, 3, 5ServiceTest.bootstrapCustomizedByServiceInitEventObserver,.sessionExpiredMessageCustomized,.errorHandlerCustomized,.sessionInitEventObserved,UIEventsTest.*,TranslationTest.*,TemplateTest.*,InstantiatorFactoryCustomizeTest.*,RemoveOldContentTest.*,BeanDiscoveryModeTest.*→ 2, 3, 5PushTest.wsWithXhrForegroundAllContextsActive,.wsWithXhrBackgroundRequestAndSessionDoesNotActive,.wsNoXhrForegroundRequestAndSessionDoesNotActive,.wsNoXhrBackgroundRequestAndSessionDoesNotActive,PushWithoutManagedExecutorTest.*→ 2, 3InvalidDeploymentTest.invalidDeploymentShouldBreakDeploy→ 2, 3 (also the only IT that assertsDeploymentValidatorrejects a bad deployment on a real container)validation.ymlstep "Verify the no-container build skips its tests" — asserts noTests run:line and aTests are skippedline from a profile-lessmvn verify→ 4flow-tests/vaadin-cdi-tests/pom.xml, antrun executionsanitize-effective-pomwith<xmlvalidate>andfailOnError=true→ 5validation.ymlstep "Run CDI ITs" — explicitenforcer:enforcegoal, evaluated once per container profile (confirmed to fail again if thearquillian-bomimport is removed) → 6Deliberately untested: the
Decide whether to rungating script (a wrong answer costs coverage or minutes, never correctness, and it fails open — it runs every container whenever it cannot determine a diff base); theSlowTests-categorised ITs, excluded by default as before the import; andKill leftover Java processes/ artifact packaging, which are cleanup steps guarded byalways().