Skip to content

fix: restore cached Gradle frontend build outputs#24314

Open
benstpierre wants to merge 2 commits into
vaadin:mainfrom
benstpierre:fix-gradle-buildfrontend-cache-outputs
Open

fix: restore cached Gradle frontend build outputs#24314
benstpierre wants to merge 2 commits into
vaadin:mainfrom
benstpierre:fix-gradle-buildfrontend-cache-outputs

Conversation

@benstpierre
Copy link
Copy Markdown

Summary

Fixes #24012.

vaadinBuildFrontend previously wrote production servlet resources into build/resources/<sourceSet>/META-INF/VAADIN, which overlaps with Gradle's processResources output. That makes the task's production bundle hard to restore safely from Gradle's build cache: a cache hit can restore the task marker/token while leaving the archive without META-INF/VAADIN/webapp assets.

This change moves the default frontendOutputDirectory for Gradle production builds to a dedicated task-owned directory:

build/vaadin-build-frontend/META-INF/VAADIN/webapp

and declares the corresponding servlet resource directory as an @OutputDirectory of vaadinBuildFrontend.

Packaging tasks now explicitly consume that task-owned output directory:

  • plain Jar: packaged at archive root
  • War: packaged under WEB-INF/classes
  • Spring Boot BootJar: packaged under BOOT-INF/classes

This keeps the archive layout unchanged while allowing Gradle to restore the production frontend bundle from the build cache.

Tests

Run from flow-plugins/flow-gradle-plugin with Java 21:

JAVA_HOME=$HOME/.sdkman/candidates/java/21.0.7-amzn ./gradlew compileKotlin compileTestKotlin
JAVA_HOME=$HOME/.sdkman/candidates/java/21.0.7-amzn ./gradlew test
JAVA_HOME=$HOME/.sdkman/candidates/java/21.0.7-amzn ./gradlew functionalTest -x test --tests 'com.vaadin.flow.gradle.VaadinSmokeTest.testBuildFrontendInProductionMode' --tests 'com.vaadin.flow.gradle.MiscSingleModuleTest.buildFrontendIncrementalBuilds_featureEnabled' --tests 'com.vaadin.flow.gradle.MiscSingleModuleTest.testBuildFrontendPropagatesBuildInfo' --tests 'com.vaadin.flow.gradle.MiscSingleModuleTest.buildFrontendBuildCacheRestoresProductionBundleForWar'
JAVA_HOME=$HOME/.sdkman/candidates/java/21.0.7-amzn ./gradlew functionalTest -x test --tests 'com.vaadin.flow.gradle.MiscSingleModuleTest.buildFrontendBuildCacheRestoresProductionBundleForWar' --tests 'com.vaadin.flow.gradle.MiscSingleModuleTest.testSpringProjectProductionMode' --tests 'com.vaadin.flow.gradle.MiscSingleModuleTest.testSpringProjectAutoProductionMode'

The new regression test verifies that after deleting the local production frontend output, cached token, and WAR, the next --build-cache -Pvaadin.productionMode build restores :vaadinBuildFrontend FROM-CACHE and the rebuilt WAR still contains the Vaadin production bundle.

@cla-assistant
Copy link
Copy Markdown

cla-assistant Bot commented May 10, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@mshabarov mshabarov added the Contribution PRs coming from the community or external to the team label May 11, 2026
@mshabarov
Copy link
Copy Markdown
Contributor

Thanks for your contribution @benstpierre ! I've started the blocked validation, let's see how gradle tests end up.

@sonarqubecloud
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

Test Results

 1 405 files  ±0   1 405 suites  ±0   1h 20m 40s ⏱️ - 2m 33s
10 137 tests ±0  10 067 ✅ ±0  70 💤 ±0  0 ❌ ±0 
10 612 runs  ±0  10 533 ✅ ±0  79 💤 ±0  0 ❌ ±0 

Results for commit 62c56fe. ± Comparison against base commit ba7d3cb.

@mshabarov mshabarov requested review from mcollovati and mshabarov May 11, 2026 11:36
@benstpierre
Copy link
Copy Markdown
Author

So anything left for me to do? This case has been insanely aggravating for years.

@mcollovati
Copy link
Copy Markdown
Collaborator

@benstpierre I'm going to review and test this PR today. I'll keep you posted.

@mcollovati
Copy link
Copy Markdown
Collaborator

@benstpierre could you please sign the CLA? Otherwise we cannot merge your patch as is, but we need to make a new PR on our own based on this one.

Copy link
Copy Markdown
Collaborator

@mcollovati mcollovati left a comment

Choose a reason for hiding this comment

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

Added a first bunch of comments; in the meanwhile I'll make some manual test

  • BuildFrontendTokenService still references build/resources/main/, but since this PR changes servletResourceOutputDirectory it should most likely mention build/vaadin-build-frontend/.

val svc = (project.tasks.getByName("vaadinBuildFrontend")
as VaadinBuildFrontendTask).getTokenService().orNull
svc?.ensureToken()
if (task.isVaadinApplicationArchiveTask()) {
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.

Why is this condition needed? Is this to avoid the configuration for sources and Javadoc JARs?
Wouldn't this check potentially break projects that define custom-named JAR tasks or using shadow/fatJAR plugins?

"Skipping task ':vaadinBuildFrontend' as it is up-to-date") }
}

@Test
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.

We should probably add a test for a plain JAR, since the plugin code allows it.

@mcollovati
Copy link
Copy Markdown
Collaborator

I set up a repository as an attempt to have some tests for the Gradle build cache. I hope this correctly covers the usage of build cache.

Here are two builds:

I plan to add a scenario also for the custom frontendOutputDirectory.

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.

vaadinBuildFrontend: redirect frontendOutputDirectory to enable Gradle build cache restore

3 participants