Skip to content

fix: only use a token file from a jar when it is from a production build - #25682

Draft
totally-not-ai[bot] wants to merge 3 commits into
mainfrom
fix/ignore-dev-mode-token-file-from-jar
Draft

fix: only use a token file from a jar when it is from a production build#25682
totally-not-ai[bot] wants to merge 3 commits into
mainfrom
fix/ignore-dev-mode-token-file-from-jar

Conversation

@totally-not-ai

@totally-not-ai totally-not-ai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

When Flow cannot find flow-build-info.json outside a jar, it falls back to a copy inside one. If a dependency packaged such a file by mistake, that file was used and it carried the folders and Node version of the machine that built the dependency, so the application failed to start. Flow now accepts a file from a jar only when it says production mode.

What changed

Behavior change: a flow-build-info.json found inside a jar is now used only if it sets productionMode: true. This affects only applications where the token file comes from a jar. A packaged (production) application always writes production mode, so it keeps working. A leftover development-mode file inside a dependency is now skipped, and a warning names the file so the dependency can be fixed. If no usable file is left, the lookup returns nothing and the application starts with its defaults instead of with another project's settings.

Other changes in DefaultApplicationConfigurationFactory:

  • The lookup now walks all candidates instead of only the first match. When the application is packaged, files with a single jar!/ in the path (the application's own jar) are tried first, then the rest.
  • A file that cannot be parsed as JSON is treated as not production mode and skipped, instead of breaking the startup.
  • The "unable to fully determine correct flow-build-info" warning is no longer suppressed for every packaged application. It is now skipped only when the chosen file really is the one in the outermost jar — which is exactly the case where the choice is certain. In the other cases the warning lists the candidates, which is when that list is most useful.

No public or protected API changed.

Test summary

# Status What the test verifies Why it matters
1 A development-mode token file inside a jar is ignored: its npmFolder and Node version do not reach the configuration This is the bug — those values point at a machine that built a dependency and break startup
2 A production-mode token file inside a jar is still read and applied A normal packaged application must keep working
3 With a development-mode and a production-mode file in jars, the production-mode one wins even though it is found second The fix must skip past bad candidates, not just reject the first one
4 In a packaged application with nested jars, the file in the outermost jar (the application's own) is used, not a dependency's Preserves the existing rule for picking the application's file
5 A token file inside a jar that is not valid JSON is ignored and startup continues Broken content in a dependency must not crash the application
6 gap The warning naming the ignored file, and the warning listing candidates when the pick is uncertain The warning is the only hint a developer gets about a broken dependency; no test captures the log
  • DefaultApplicationConfigurationFactoryTest.create_onlyDevelopmentModeTokenFileInsideJar_tokenFileIsIgnored → 1
  • DefaultApplicationConfigurationFactoryTest.create_productionModeTokenFileInsideJar_tokenFileIsUsed → 2
  • DefaultApplicationConfigurationFactoryTest.create_developmentModeTokenFileInsideJarIsFoundFirst_productionModeOneIsUsed → 3
  • DefaultApplicationConfigurationFactoryTest.create_packagedApplicationWithNestedJars_tokenFileOfTheApplicationIsUsed → 4
  • DefaultApplicationConfigurationFactoryTest.create_unparseableTokenFileInsideJar_tokenFileIsIgnored → 5

Left untested on purpose: the exact wording of the log messages, and the test helpers (mockJarTokenFile, mockTokenFileUrl), which only build URLs used by the tests above.

When no flow-build-info.json is found outside a jar, the lookup falls
back to a copy inside one. A copy packaged into a dependency by mistake
is written by prepare-frontend, so it carries the folders and the Node
version of the machine that built the dependency, and the application
fails to start with a folder it has never heard of.

Adds a failing test for that case and one that keeps the packaged
application case, where the token file of the application itself is
inside a jar, working.
The flow-build-info.json lookup skips copies inside jars and falls back
to one only when the application has none of its own, which is the case
for a packaged application. A copy that a dependency packages by mistake
was then used as well, and as prepare-frontend writes it, it brought the
project folders and the Node version of the machine that built the
dependency, failing the startup with a folder that does not exist.

A file from a jar is now used only when it declares production mode,
which a packaged application always does and a file left over from a
development build never does. The ignored file is named in a warning so
that the mistake in the dependency can be fixed.
The warning about not being able to tell which flow-build-info.json is
the right one was left out whenever the application looked packaged into
a jar, even when the file was not the one the rule for a packaged
application points at, which is when knowing about the other candidates
helps the most.

The warning is now left out only when the file is the one in the
outermost jar, and the cases with more than one file inside a jar are
covered by tests.
@totally-not-ai

Copy link
Copy Markdown
Contributor Author

Type of change

  • Bugfix

How to test

  1. Build any Vaadin application in development mode, so that
    target/classes/META-INF/VAADIN/config/flow-build-info.json is
    written.
  2. Package that file into a jar of its own,
    jar cf addon.jar -C target/classes META-INF, and add the jar to the
    class path of a second application.
  3. Delete target/classes/META-INF/VAADIN/config/flow-build-info.json
    of the second application, so that only the copy in the jar is left,
    and start it.
  4. Before: the startup fails with Running project in development mode with no access to folder …, naming the folder of the first
    application. After: the file is ignored with a warning that names it,
    and the application starts.
Test coverage

In DefaultApplicationConfigurationFactoryTest:

  • create_onlyDevelopmentModeTokenFileInsideJar_tokenFileIsIgnored — a
    file written by prepare-frontend and packaged into a dependency is
    ignored instead of failing the startup.
  • create_productionModeTokenFileInsideJar_tokenFileIsUsed — the file
    of a packaged application is still used.
  • create_developmentModeTokenFileInsideJarIsFoundFirst_productionModeOneIsUsed
    — a development mode file returned first does not hide the production
    one.
  • create_packagedApplicationWithNestedJars_tokenFileOfTheApplicationIsUsed
    — with nested jars, the file of the application wins over the one of a
    dependency.
  • create_unparseableTokenFileInsideJar_tokenFileIsIgnored — content
    that is not JSON is ignored.

The tests that read the file from the class path now use a plain class
path URL instead of a jar one, which is what they were about.

API changes

None. getTokenFileFromClassloader keeps its signature; the new
isProductionModeTokenFile is private.

Note

#25681 touches the same method, and makes the counting of nested
archives understand the jars of Spring Boot 3.2 and newer. The two are
independent, so whichever is merged second needs a small conflict
resolution: count the archive levels with countArchiveLevels in
every place this change counts jar!/.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

 1 440 files  ±0   1 524 suites  ±0   1h 29m 41s ⏱️ - 4m 56s
12 065 tests +5  11 997 ✅ +5  68 💤 ±0  0 ❌ ±0 
12 383 runs  +5  12 315 ✅ +5  68 💤 ±0  0 ❌ ±0 

Results for commit 5abc5f2. ± Comparison against base commit 980ac5b.

@sonarqubecloud

Copy link
Copy Markdown

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.

0 participants