Skip to content

fix(devloop): recompile the app when a reactor sibling leaves the loop (#25465) (CP: 25.3) - #25642

Merged
vaadin-bot merged 1 commit into
25.3from
cherry-pick-25465-to-25.3-1789047192179
Sep 10, 2026
Merged

fix(devloop): recompile the app when a reactor sibling leaves the loop (#25465) (CP: 25.3)#25642
vaadin-bot merged 1 commit into
25.3from
cherry-pick-25465-to-25.3-1789047192179

Conversation

@vaadin-bot

Copy link
Copy Markdown
Collaborator

This PR cherry-picks changes from the original PR #25465 to branch 25.3.

Original PR description

The module set is derived from the app's resolved classpath, so dropping a sibling dependency removes both the sibling's target/classes and the sibling itself from the loop. That module-set change rebuilt Compile, whose constructor re-seeded compiledAgainst from the project as it now stood - overwriting the app's classpath baseline with the already-moved classpath. classpathForced then saw no movement and forced no recompile, so the apply fell through to the drift restart and reported Stable while the page broke with ClassNotFoundException. An external jar was unaffected: it changes no module, so the baseline survived and the forced recompile fired.

Compile now takes the outgoing baseline and carries compiledAgainst over for every module still in the loop. The app module is recompiled whole, and javac's diagnostic ends the apply as Failed before the restart leg runs. Only the classpath baseline is carried; per-file stamps still start afresh, as they describe a different build.

#25465)

The module set is derived from the app's resolved classpath, so dropping
a sibling dependency removes both the sibling's target/classes and the
sibling itself from the loop. That module-set change rebuilt Compile,
whose constructor re-seeded compiledAgainst from the project as it now
stood - overwriting the app's classpath baseline with the already-moved
classpath. classpathForced then saw no movement and forced no recompile,
so the apply fell through to the drift restart and reported Stable while
the page broke with ClassNotFoundException. An external jar was
unaffected: it changes no module, so the baseline survived and the
forced recompile fired.

Compile now takes the outgoing baseline and carries compiledAgainst over
for every module still in the loop. The app module is recompiled whole,
and javac's diagnostic ends the apply as Failed before the restart leg
runs. Only the classpath baseline is carried; per-file stamps still
start afresh, as they describe a different build.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Carrying the outgoing classpath baseline reroutes the apply from a silent restart to a compile failure

flowchart LR
    subgraph Before
        direction TB
        B1["compileFor(): new Compile(project)"] -->|re-seeds baseline from moved classpath| B2["compiledAgainst[app] = moved classpath"]
        B2 -->|classpathForced() sees no move| B3["forced = [] empty"]
        B3 -.->|no recompile, falls to drift leg| B4["restart, reports Stable (ClassNotFoundException on next load)"]
    end
    subgraph After
        direction TB
        A1["compileFor(): new Compile(project, previous)"] -->|carries baseline for surviving modules| A2["compiledAgainst[app] = old classpath (new)"]:::changed
        A2 -->|classpathForced() sees the move| A3["forced = [Main.java]"]:::changed
        A3 -->|recompiles whole app module| A4["javac fails, apply ends Failed before restart"]:::changed
    end
    Before ~~~ After
    classDef changed stroke:#c9a227,stroke-width:3px
Loading

When a reactor sibling leaves the loop, the module set changes and TransactionEngine.compileFor() rebuilds the Compile baseline. Before, new Compile(project) re-seeded compiledAgainst from the already-moved classpath, so classpathForced() saw no movement, forced no recompile, and the apply fell through to the drift restart — reporting Stable while the page broke with ClassNotFoundException. After, new Compile(project, previous) carries the old baseline for each surviving module, so classpathForced() returns the app's sources, javac recompiles the whole module and fails before the restart leg runs (per the PR description). Highlighted nodes are the carried-baseline path.

Diagram Bot draws the mechanism this pull request touches; it does not review the change. Verify it against the diff.

Generated by Diagram Bot for issue #25642 ·

@vaadin-bot

Copy link
Copy Markdown
Collaborator Author

This PR is eligible for auto-merging policy, so it has been approved automatically. If there are pending conditions, auto merge (with 'squash' method) has been enabled for this PR [Message is sent from bot]

@vaadin-bot
vaadin-bot enabled auto-merge (squash) September 10, 2026 13:47
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

 1 439 files   1 523 suites   1h 34m 27s ⏱️
12 023 tests 11 955 ✅ 68 💤 0 ❌
12 341 runs  12 273 ✅ 68 💤 0 ❌

Results for commit f75b79c.

@vaadin-bot
vaadin-bot merged commit ad296f0 into 25.3 Sep 10, 2026
42 checks passed
@vaadin-bot
vaadin-bot deleted the cherry-pick-25465-to-25.3-1789047192179 branch September 10, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants