Changes since 25.2.7
Breaking changes
-
Do not override the minimum frontend package age configured for the package manager (#25173) (CP: 25.2)
Commit · Pull requestThe
minimumFrontendPackageAgeDaysparameter defaulted to1and was always passed as a command line argument to the package manager. A command line argument takes precedence over every configuration source of npm, pnpm and bun, so a project that had configuredmin-release-agein its.npmrc(orminimumReleaseAgeinpnpm-workspace.yaml) silently got the Vaadin default instead —mvn vaadin:build-frontendand a manually runnpm installdisagreed on which package versions were allowed to be installed. The parameter is now unset by default (Integer/nullrather thanint/1): - A value configured on the Vaadin side is used as is,0still disables the check. - When nothing is configured, the package manager is asked what it resolves for its own minimum release age setting. If it already has one, no argument is passed and the package manager applies its own configuration; this is logged at info level along with the parameter to set in order to override it. - Only when neither is configured does the one-day default (TaskRunNpmInstall.DEFAULT_MINIMUM_FRONTEND_PACKAGE_AGE_DAYS) apply.
Fixes
-
Stabilize Gradle dependency JAR fingerprint (#25388) (CP: 25.2)
Commit · Pull requestThis is a follow-up to the Gradle build-cache work originally contributed in #24314 and landed in #25001. The standalone scalar provider in
VaadinBuildFrontendTaskcould be evaluated before a project dependency's JAR output existed. A cold build therefore storedvaadinBuildFrontendwith a different dependency fingerprint and cache key than subsequent unchanged builds. This derives the same lightweight JAR name-and-size fingerprint fromdependencyJarFiles.elements. The provider now retains the file collection's build dependencies while avoiding full content hashing of large external classpaths. The newMiscMultiModuleTestregression proves both sequences with build cache and configuration cache enabled: | Build | Before | After | | --- | --- | --- | | Cold checkout |SUCCESS(key A) |SUCCESS| | Immediate unchanged build |SUCCESS(key B) |UP-TO-DATE| | Fresh relocated checkout |FROM-CACHE(key A) |FROM-CACHE| | Immediate unchanged relocated build |FROM-CACHE(key B) |UP-TO-DATE| Please target this for 25.2 after merging tomain. -
Let the Gradle classpath filter be saved in the configuration cache (#25398) (CP: 25.2)
Commit · Pull request · IssueThe filter was built by chaining Predicate.and(), or() and negate(). Those return lambdas that live inside the JDK, and Gradle cannot write them into a configuration cache entry. A project with a file dependency such as
implementation files('libs/some.jar')keeps the filter in the saved task graph, so the build failed withmodule java.base does not "opens java.util.function". Replace the chain with a small class that holds only the configured include and exclude patterns, and pass the component filter to Gradle as a named class instead of a lambda. -
Stop passing --scripts-prepend-node-path to npm (#25333) (CP: 25.2)
Commit · Pull requestnpm 12 removed the long-deprecated
--scripts-prepend-node-pathconfig and now rejects unknown CLI flags. As a result everynpm installexecuted bybuild-frontendfails with:Unknown cli flagwhenever a global npm 12 is used. The flag dates back to when Flow ran npm 6, where it made lifecycle scripts run with the same node binary that executesnpm-cli.js. Since npm 7, script execution moved to@npmcli/run-script, which buildsPATHfrom thenode_modules/.binfolders, the node-gyp bin folder and the inheritedPATH— it never looks at this config. Flow requires npm 11.3 or newer, so no supported npm version honours the flag. Dropping it changes nothing except that npm 12 no longer fails.
Removes the--scripts-prepend-node-path=trueflag thatFrontendTools#getNpmExecutableappended to every generated npm command line, and updatesFrontendToolsTestaccordingly (the default npm command is now 4 elements instead of 5). -
Avoid format strings in FrontendUtils.console (#25048) (CP: 25.2)
Commit · Pull request · IssueFrontendUtils.console()passed a caller-controlledformatparameter straight intoString.format(), which static analysis tools flag as CWE-134 (uncontrolled format string), since the method's contract does not guarantee the argument is a compile-time constant. Additionally, review feedback pointed out that even after removingString.format(),console(String, String)still let the color and message arguments be swapped by mistake, since both were plainStrings. -
Consider about:blank a safe URL (#25317) (CP: 25.2)
Commit · Pull request · IssueThe safe URL check is based on the URL scheme, and
aboutis not in the default set of safe schemes. As a side effect, this also blocked legitimate uses ofabout:blank, such as setting it as the initial source of anIFrame.about:blankis now accepted regardless of the configured safe schemes, since it renders an empty document and cannot run scripts. The comparison is case-insensitive, soAbout:Blankis treated the same way. Otherabout:URLs (e.g.about:config, or lookalikes such asabout:blank:evil) are unchanged: they are still rejected unless theaboutscheme is explicitly configured as safe via thesafeUrlSchemesinit parameter. ### Changes -UrlUtil.isSafeUrl(...)short-circuits totruefor a trimmed, case-insensitive match onabout:blank, before the scheme-based check. - Javadoc updated onUrlUtil.isSafeUrl,Constants.DEFAULT_URL_SAFE_SCHEMESandInitParameters.URL_SAFE_SCHEMESto document the exception. - New tests inUrlUtilTestcoveringabout:blank(default schemes, mixed case, and a scheme set that excludesabout) and the otherabout:URLs that must stay unsafe. -
Guard filter and sorting callbacks against EmptyDataProvider (#20828) (#25229) (CP: 25.2)
Commit · Pull request · IssueGuards
filterOrSortingChangedinAbstractListDataViewagainst instances where the underlying data provider isDataCommunicator.EmptyDataProvider. This preventsNullPointerExceptionwhen configuring in-memory filters or sort comparators on components before items or an explicit data provider have been initialized. -
Handling of null in HierarchicalDataProvider refreshItem(null, true) (#25248) (CP: 25.2)
Commit · Pull request · IssueImproves support for refreshing the "virtual root" (i.e., the parent of root-level items, represented by
null) in hierarchical data providers. Updates the documentation and implementation to clarify that passingnullas the item and settingrefreshChildrentotrueis equivalent to a full hierarchy refresh, while passingnullwithrefreshChildrenset tofalsethrows exception. The changes also add comprehensive tests to verify this behavior.