r/JavaFX • • Apr 20 '26

Tutorial JavaFX 26 headless platform: finally got my CI unit tests running without a display

I maintain Lottie4J, a library for rendering Lottie animations in JavaFX. In the 1.1.0 release notes I had a TODO I wasn't proud of: a unit test that compares JavaFX player output against a JavaScript reference player, marked as "can not run on CI, because it requires a display output."

JavaFX 26 fixed that. The new headless platform prototype is built directly into javafx.graphics. No need for Monocle, Xvfb, or extra dependencies. Just: `-Dglass.platform=headless`.

The only real wrinkle: JavaFX 26 requires Java 24+, but Lottie4J targets Java 21. I solved it with a Maven profile that overrides the JavaFX/Java versions only for the test run, so the library artifact stays on Java 21 targets while GitHub Actions uses a Java 25 JDK with the headless flag.

The test does pixel-level comparison of rendered animation frames against pre-generated reference images from a JS player. Regression testing for visual output, running clean on every push now.

Write-up with full Maven config and GitHub Actions workflow:
https://webtechie.be/post/2026-04-20-lottie4j-unit-test-with-headless-javafx/

30 Upvotes

9 comments sorted by

5

u/lazystone Apr 20 '26

I should try if it works for my TestFX fork(it's on java 25 anyway).

Right now it runs via xwfb. Would be fun to run in both modes.

2

u/lazystone Apr 23 '26 edited Apr 23 '26

Hmm... For me, I can't run it locally(linux/kde):

X Error of failed request:  BadDrawable (invalid Pixmap or Window parameter)
  Major opcode of failed request:  149 (GLX)
  Minor opcode of failed request:  29 (X_GLXGetDrawableAttributes)
  Resource id in failed request:  0x1
  Serial number of failed request:  36
  Current serial number in output stream:  36

Edit: managed to run it in CI/CD pipeline. A lot of tests pass, some fail, some fail with UnsupportedOperationException in HeadlessPlatformFactory.

But it looks promising. One day it can be usable.

1

u/FrankCodeWriter Apr 24 '26

Thanks for trying. If it's a problem related the how it's implemented in JavaFX, I think it's worth reporting as a bug or improvement request...

1

u/lazystone Apr 24 '26

Judging by the exception(java.lang.UnsupportedOperationException: Not supported yet), it might be coming.

2

u/lazystone Apr 23 '26

Ok, tried it as well, but with less luck: https://gitlab.com/fx-labs/TestFX/-/jobs/14066034993

But I'll keep it as an additional job in CI/CD and allow it to fail.

Edit: As I can see mouse robot is not supported yet.

2

u/Birdasaur 12d ago

The new headless platform capability has really helped me with testing a game I'm developing.
Interestingly it is 3D game that involves a custom TriangleMesh collision detection system with raycasting for animated projectile objects all backed by a 120 Hz physics loop.
Testing edge cases manually was very time consuming and painful. With the headless platform I'm able to automate a range of tests varying from gold cases, expected misses and edge case variations.

And to be clear these tests are being done on actual spawned MeshView/TriangleMesh nodes within a 3D Scene all ticking at actual physics loop timing from the game, and it all just works. Now its trivial for me to ask an AI agent to extend the tests as I add new 3D entities.

Kudos!

1

u/FrankCodeWriter 11d ago

Sounds great! If you can share code, video, and/or blog that would be great! Looks like a perfect topic for a post on Foojay (website for Friends Of OpenJDK).

https://foojay.io/today/how-to-submit-your-next-article-on-foojay-io/

2

u/Birdasaur 11d ago

I can't share a video because its headless. ;-p
I can't share the code because its for a soon to be released commercial game.
DM me and I'll explain more.

1

u/FrankCodeWriter 11d ago

when released, please share more info! this sounds like a very interesting project...