What changed, and why it matters
This commit updates Sparrow Wallet's build system to use Java 25, JavaFX 25, Gradle 9.1, and newer GitHub Actions versions. It also adjusts native-access permissions and module settings needed for the newer Java version. The change is a routine platform upgrade, not a security patch. There is no direct evidence in the commit that it fixes a known vulnerability, but any major runtime upgrade can introduce or remove security-relevant behavior.
Treat as a routine maintenance upgrade. Review the Java 25 and JavaFX 25 release notes for any security fixes or breaking changes, verify the updated Gradle wrapper checksum, and test that the new native-access flags do not expose unintended native code paths. No urgent security action is required based solely on this commit.
Security signals we found
Major JDK/JavaFX version upgrade (22 -> 25)
New --enable-native-access flags broaden native library access for several modules
Gradle wrapper binary and script changed (supply-chain surface area)
Dependency version bumps (richtextfx, jlink plugin)
No explicit security fix or advisory referenced in commit
Evidence from the diff
The diff bumps the JDK from 22.0.2 to 25.0.0, JavaFX from 23.0.2 to 25, Gradle from 8.14.3 to 9.1.0, GitHub checkout/setup-java actions to v5, richtextfx to 0.11.6, and the beryx jlink plugin to 3.1.4-rc. It adds several –enable-native-access flags (drongo, javafx.graphics, jSerialComm, usb4java) and an –add-reads for reactfx, plus renames an undo module. A single UI call on macOS is wrapped in Platform.runLater. No vulnerability, CVE, or security advisory is mentioned.
Changed components
Sparrow Wallet build/packaging pipelineGitHub Actions package workflowGradle build configurationJVM launch arguments (applicationDefaultJvmArgs and jlink launcher jvmArgs)Java module configuration (extraJavaModuleInfo)macOS application menu initialization (AppController.java)Inspect captured patch +26 / −20
diff --git a/.github/workflows/package.yaml b/.github/workflows/package.yaml
index 8883361..1c3b2e1 100644
--- a/.github/workflows/package.yaml
+++ b/.github/workflows/package.yaml
@@ -12,14 +12,14 @@ jobs:
matrix:
os: [windows-2022, ubuntu-22.04, ubuntu-22.04-arm, macos-13, macos-14]
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
with:
submodules: true
- - name: Set up JDK 22.0.2
- uses: actions/setup-java@v4
+ - name: Set up JDK 25
+ uses: actions/setup-java@v5
with:
distribution: 'temurin'
- java-version: '22.0.2'
+ java-version: '25.0.0'
- name: Show Build Versions
run: ./gradlew -v
- name: Build with Gradle
diff --git a/build.gradle b/build.gradle
index 6e9134e..4afa528 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
plugins {
id 'application'
id 'org-openjfx-javafxplugin'
- id 'org.beryx.jlink' version '3.1.2'
+ id 'org.beryx.jlink' version '3.1.4-rc'
id 'org.gradlex.extra-java-module-info' version '1.13'
id 'io.matthewnelson.kmp.tor.resource-filterjar' version '408.16.3'
}
@@ -33,7 +33,7 @@ tasks.withType(AbstractArchiveTask) {
}
javafx {
- version = headless ? "18" : "23.0.2"
+ version = headless ? "18" : "25"
modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.swing', 'javafx.graphics' ]
}
@@ -58,7 +58,7 @@ dependencies {
exclude group: 'org.slf4j'
}
implementation('org.flywaydb:flyway-core:9.22.3')
- implementation('org.fxmisc.richtext:richtextfx:0.10.4')
+ implementation('org.fxmisc.richtext:richtextfx:0.11.6')
implementation('no.tornado:tornadofx-controls:1.0.4')
implementation('com.google.zxing:javase:3.4.0') {
exclude group: 'com.beust', module: 'jcommander'
@@ -142,6 +142,10 @@ application {
mainClass = 'com.sparrowwallet.sparrow.SparrowWallet'
applicationDefaultJvmArgs = ["-XX:+HeapDumpOnOutOfMemoryError",
+ "--enable-native-access=com.sparrowwallet.drongo",
+ "--enable-native-access=javafx.graphics",
+ "--enable-native-access=com.fazecast.jSerialComm",
+ "--enable-native-access=org.usb4java",
"--enable-native-access=io.github.doblon8.jzbar",
"--add-opens=javafx.graphics/com.sun.javafx.css=org.controlsfx.controls",
"--add-opens=javafx.graphics/javafx.scene=org.controlsfx.controls",
@@ -191,7 +195,12 @@ jlink {
options = ['--strip-native-commands', '--strip-java-debug-attributes', '--compress', 'zip-6', '--no-header-files', '--no-man-pages', '--ignore-signing-information', '--exclude-files', '**.png', '--exclude-resources', 'glob:/com.sparrowwallet.merged.module/META-INF/*']
launcher {
name = 'sparrow'
- jvmArgs = ["--enable-native-access=io.github.doblon8.jzbar",
+ jvmArgs = ["--enable-native-access=com.sparrowwallet.drongo",
+ "--enable-native-access=javafx.graphics",
+ "--enable-native-access=com.sparrowwallet.merged.module",
+ "--enable-native-access=com.fazecast.jSerialComm",
+ "--enable-native-access=org.usb4java",
+ "--enable-native-access=io.github.doblon8.jzbar",
"--add-opens=javafx.graphics/com.sun.javafx.css=org.controlsfx.controls",
"--add-opens=javafx.graphics/javafx.scene=org.controlsfx.controls",
"--add-opens=javafx.controls/com.sun.javafx.scene.control.behavior=org.controlsfx.controls",
@@ -224,6 +233,7 @@ jlink {
"--add-reads=com.sparrowwallet.merged.module=org.bouncycastle.pg",
"--add-reads=com.sparrowwallet.merged.module=org.bouncycastle.provider",
"--add-reads=com.sparrowwallet.merged.module=kotlin.stdlib",
+ "--add-reads=com.sparrowwallet.merged.module=org.reactfx.reactfx",
"--add-reads=kotlin.stdlib=kotlinx.coroutines.core",
"--add-reads=org.flywaydb.core=java.desktop"]
@@ -419,10 +429,10 @@ extraJavaModuleInfo {
requires('javafx.graphics')
requires('org.fxmisc.flowless')
requires('org.reactfx.reactfx')
- requires('org.fxmisc.undo.undofx')
+ requires('org.fxmisc.undo')
requires('org.fxmisc.wellbehaved')
}
- module('org.fxmisc.undo:undofx', 'org.fxmisc.undo.undofx') {
+ module('org.fxmisc.undo:undofx', 'org.fxmisc.undo') {
requires('javafx.base')
requires('javafx.controls')
requires('javafx.graphics')
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 1b33c55..8bdaf60 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index d4081da..2e11132 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index 23d15a9..adff685 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# Copyright © 2015-2021 the original authors.
+# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
-CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
diff --git a/gradlew.bat b/gradlew.bat
index 5eed7ee..e509b2d 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -70,11 +70,10 @@ goto fail
:execute
@rem Setup the command line
-set CLASSPATH=
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java
index 4dbe740..dc736c7 100644
--- a/src/main/java/com/sparrowwallet/sparrow/AppController.java
+++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java
@@ -463,7 +463,7 @@ public class AppController implements Initializable {
settings, new SeparatorMenuItem(),
tk.createHideMenuItem(SparrowWallet.APP_NAME), tk.createHideOthersMenuItem(), tk.createUnhideAllMenuItem(), new SeparatorMenuItem(),
tk.createQuitMenuItem(SparrowWallet.APP_NAME));
- tk.setApplicationMenu(defaultApplicationMenu);
+ Platform.runLater(() -> tk.setApplicationMenu(defaultApplicationMenu));
fileMenu.getItems().removeIf(item -> item.getStyleClass().contains("osxHide"));
toolsMenu.getItems().removeIf(item -> item.getStyleClass().contains("osxHide"));
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.