Skip to content

BryanL43/SpringJavaFXGraal

Repository files navigation

SpringJavaFXGraal

Overview

A minimal setup for a Windows desktop application compiled to a native image with GraalVM. Uses Spring Boot JDBC and JavaFX, and builds with Maven.

Includes:

  • Spring Boot JDBC for data access
  • Optional AtlantaFX styling, remove the dependencies if you are not using it
  • Inno Setup configuration for a custom non-admin installer
  • CI/CD workflow to build and package the installer for release

Quick Specifications

  • Windows 10/11 OS
  • Java 25 (LTS)
  • GraalVM 25, Windows x64
  • Spring Boot 4.0.4
  • JavaFX 22
  • PostgreSQL 42.7.3
  • Inno Setup 6.7.1

Installation

Prerequisites:

Install Visual Studio Build Tools and the Windows SDK. Follow the official GraalVM guide: https://www.graalvm.org/latest/getting-started/windows/#prerequisites-for-native-image-on-windows

GraalVM installation:

  1. Download GraalVM binaries: GraalVM.org
version: GraalVM 25, Windows x64
  1. Extract binaries to your preferred location:

Example:

C:\GraalVM\graalvm-jdk-25.0.2+10.1

Verify the \bin path:

C:\GraalVM\graalvm-jdk-25.0.2+10.1\bin
  1. Set required environment variables using Command Prompt:

Example:

setx GRAALVM_HOME "C:\GraalVM\graalvm-jdk-25.0.2+10.1"
setx JAVA_HOME "C:\GraalVM\graalvm-jdk-25.0.2+10.1"
setx PATH "%PATH%;%JAVA_HOME%\bin"

Restart Command Prompt, then verify:

java --version

Sample output expectation:

java 25.0.2 2026-01-20 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 25.0.2+10.1 (build 25.0.2+10-LTS-jvmci-b01)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 25.0.2+10.1 (build 25.0.2+10-LTS-jvmci-b01, mixed mode, sharing)

Note

GraalVM is used to build the native image. The application runs as a native executable and does not require a separate JVM.

Usage

  1. Navigate to the project directory:
cd <your-repo-directory>
  1. Create the dev configuration:

Copy the example file and rename it:

cp src\main\resources\application-dev.yml.example src\main\resources\application-dev.yml

Open src\main\resources\application-dev.yml and replace placeholders with your settings.

  1. Set active profile (points to dev configuration):

Powershell:

$env:SPRING_PROFILES_ACTIVE="dev"

Command Prompt:

set SPRING_PROFILES_ACTIVE=dev
  1. Build the application JAR:
.\mvnw clean package

Builds the application and runs TestFX tests in headless mode using Monocle.

  1. Generate Spring Ahead-of-Time (AOT) Artifacts and Reachability Metadata:
.\mvnw test -Pnative-trace

This attaches the GraalVM tracing agent to TestFX to collect reachability metadata automatically. Note that it will take control of your I/O because the tracing agent requires a non-headless UI.

Warning

Ensure your tests behave like end-to-end tests and exercise ALL UI flows through real user interactions.

  1. Build the native executable:
.\mvnw package -Pnative
  1. Build the installer via CLI (Inno Setup):
iscc installer.iss

If iscc is not in your PATH, use the full path to the compiler, for example:

& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" installer\installer.iss

Optional

Skip tests by adding -DskipTests to any of the above Maven command.

Extra

For local development, use the run configuration in the .run directory or run manually:

.\mvnw javafx:run

This builds the JAR and runs the application.

GitHub Secrets

The CI/CD workflow requires database credentials stored as GitHub Secrets.

  1. Go to your repository on GitHub
  2. Open Settings → Secrets and variables → Actions
  3. Add the following Repository secrets:
  • SPRING_DATASOURCE_JDBCURL
  • SPRING_DATASOURCE_USERNAME
  • SPRING_DATASOURCE_PASSWORD

Use the same values as your local application-dev.yml.

Example:

  • SPRING_DATASOURCE_JDBCURL=jdbc:postgresql://localhost:5432/your_database
  • SPRING_DATASOURCE_USERNAME=your_username
  • SPRING_DATASOURCE_PASSWORD=your_password

These secrets are used by the workflow to run tests, build the native executable, and package the installer.

Demo Video

Watch demo

Note

A video to show the usage. Database setup instructions are not included.

Cautionary Tale

Why use Spring Boot JDBC instead of JPA?

JPA relies on Hibernate ORM, which depends on reflection. GraalVM has strict constraints around reflection, which makes Hibernate integration notoriously difficult. Therefore, JDBC is the more viable choice, as it provides greater control and stability.

Attempts to work around these limitations require extensive configuration and often fail. I spent way too much time trying to make this work without success.

A potentially useful reference for enabling Hibernate with GraalVM is:

https://github.com/Vadym79/aws-lambda-java-25/tree/main/aws-lambda-java-25-hibernate-aurora-dsql-as-graalvm-native-image

And it's associating forum discussion:

https://discourse.hibernate.org/t/how-to-correctly-disable-byte-buddy-for-graalvm-native-image/12163

This example uses Hibernate and HikariCP directly. It does not include Spring Boot.

Libraries

References

License

This project is licensed under the MIT License.

About

A minimal Windows desktop application template compiled to a GraalVM native image. Uses Spring Boot JDBC and JavaFX, built with Maven, and includes Inno Setup configuration for a non-admin installer, with optional AtlantaFX styling.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors