Related to #25682
Background
META-INF/VAADIN/config/flow-build-info.json, the token file, carries the
configuration the build hands over to the runtime. One file serves two very
different purposes:
prepare-frontend writes a development mode file: productionMode: false
plus the absolute paths of the machine that runs the build (npmFolder,
frontendFolder, node.version, the Java source and resource folders, ...).
See BuildFrontendUtil.propagateBuildInfo.
build-frontend rewrites the same file for production: it removes all of
those and sets productionMode: true. See BuildFrontendUtil.updateBuildFile.
The file therefore has two distinct shapes, and which one a reader has in front
of it is only visible from the content.
Problem
One name for two shapes forces workarounds in the build plugins and in the
runtime:
- The runtime cannot tell which copy on the class path belongs to the
application. DefaultApplicationConfigurationFactory drops candidates whose
URL ends with jar!/META-INF/VAADIN/config/flow-build-info.json, falls back
to a copy inside a jar for a packaged application, counts nested archive
separators to work out which jar is the application's, and logs "Unable to
fully determine correct flow-build-info" when it cannot decide.
- A development mode file packaged into a dependency by mistake is applied to
the application. It points npmFolder at a folder on the machine that built
the dependency, so the application fails to start with "Running project in
development mode with no access to folder ...". Add-ons have to exclude the
file from their artifact by hand, as
flow-tests/test-express-build/java-add-on/pom.xml does.
- The Maven plugin deletes the file after a production build
(BuildFrontendMojo, FlowLifecycleParticipant) so that starting the
application from an IDE afterwards does not read a stale
productionMode: true token.
- The Gradle plugin keeps the production tree in a separate output directory to
avoid "a second, conflicting META-INF/VAADIN/config/flow-build-info.json" in
the archive, and manages the single file through a build service and a cached
copy (FlowPlugin, VaadinBuildFrontendTask, BuildFrontendTokenService).
Proposal
Write two files instead of one:
META-INF/VAADIN/config/flow-development-mode-info.json, written by
prepare-frontend. Describes the project on this machine and is not meant to
be distributed in an artifact.
META-INF/VAADIN/config/flow-production-mode-info.json, written by
build-frontend. Contains no machine-specific paths, is packaged into the
application and may be read from inside a jar.
The runtime then reads the production file from anywhere, including a jar, and
the development file only from the output of the project itself. The rest falls
out: no productionMode flag to inspect before trusting a file, no guessing
which jar owns which copy, and a development file inside a dependency is never
looked for in the first place.
To decide
- An application packaged as a plain or shaded jar in development mode has its
development file inside a jar as well. Either that keeps working (read the
development file from a jar when the project folder it names exists on this
machine) or the packaging is declared unsupported in development mode.
- Compatibility: artifacts built by older versions carry only
flow-build-info.json, so the runtime has to keep reading it for at least one
major, with the current content-based rules.
vaadin.frontend.token.file (FrontendUtils.PARAM_TOKEN_FILE) and
vaadin.flow.tokenFilePath point at a single file and need a decision.
- Other places that name the file:
flow-devloop-daemon, the Gradle plugin
README, and anything outside this repository that reads the token file.
Affected
flow-server (FrontendUtils.TOKEN_FILE, AbstractConfigurationFactory,
DefaultApplicationConfigurationFactory, ServletDeployer, DAUUtils),
flow-plugin-base, flow-maven-plugin, flow-gradle-plugin,
flow-devloop-daemon, and the documentation.
Related to #25682
Background
META-INF/VAADIN/config/flow-build-info.json, the token file, carries theconfiguration the build hands over to the runtime. One file serves two very
different purposes:
prepare-frontendwrites a development mode file:productionMode: falseplus the absolute paths of the machine that runs the build (
npmFolder,frontendFolder,node.version, the Java source and resource folders, ...).See
BuildFrontendUtil.propagateBuildInfo.build-frontendrewrites the same file for production: it removes all ofthose and sets
productionMode: true. SeeBuildFrontendUtil.updateBuildFile.The file therefore has two distinct shapes, and which one a reader has in front
of it is only visible from the content.
Problem
One name for two shapes forces workarounds in the build plugins and in the
runtime:
application.
DefaultApplicationConfigurationFactorydrops candidates whoseURL ends with
jar!/META-INF/VAADIN/config/flow-build-info.json, falls backto a copy inside a jar for a packaged application, counts nested archive
separators to work out which jar is the application's, and logs "Unable to
fully determine correct flow-build-info" when it cannot decide.
the application. It points
npmFolderat a folder on the machine that builtthe dependency, so the application fails to start with "Running project in
development mode with no access to folder ...". Add-ons have to exclude the
file from their artifact by hand, as
flow-tests/test-express-build/java-add-on/pom.xmldoes.(
BuildFrontendMojo,FlowLifecycleParticipant) so that starting theapplication from an IDE afterwards does not read a stale
productionMode: truetoken.avoid "a second, conflicting META-INF/VAADIN/config/flow-build-info.json" in
the archive, and manages the single file through a build service and a cached
copy (
FlowPlugin,VaadinBuildFrontendTask,BuildFrontendTokenService).Proposal
Write two files instead of one:
META-INF/VAADIN/config/flow-development-mode-info.json, written byprepare-frontend. Describes the project on this machine and is not meant to
be distributed in an artifact.
META-INF/VAADIN/config/flow-production-mode-info.json, written bybuild-frontend. Contains no machine-specific paths, is packaged into the
application and may be read from inside a jar.
The runtime then reads the production file from anywhere, including a jar, and
the development file only from the output of the project itself. The rest falls
out: no
productionModeflag to inspect before trusting a file, no guessingwhich jar owns which copy, and a development file inside a dependency is never
looked for in the first place.
To decide
development file inside a jar as well. Either that keeps working (read the
development file from a jar when the project folder it names exists on this
machine) or the packaging is declared unsupported in development mode.
flow-build-info.json, so the runtime has to keep reading it for at least onemajor, with the current content-based rules.
vaadin.frontend.token.file(FrontendUtils.PARAM_TOKEN_FILE) andvaadin.flow.tokenFilePathpoint at a single file and need a decision.flow-devloop-daemon, the Gradle pluginREADME, and anything outside this repository that reads the token file.
Affected
flow-server(FrontendUtils.TOKEN_FILE,AbstractConfigurationFactory,DefaultApplicationConfigurationFactory,ServletDeployer,DAUUtils),flow-plugin-base,flow-maven-plugin,flow-gradle-plugin,flow-devloop-daemon, and the documentation.