<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Frank Delporte</title>
    <description>The latest articles on DEV Community by Frank Delporte (@fdelporte).</description>
    <link>https://dev.to/fdelporte</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F395015%2Fd00fa8a9-663a-48f3-b950-dd3e5d55278f.jpg</url>
      <title>DEV Community: Frank Delporte</title>
      <link>https://dev.to/fdelporte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fdelporte"/>
    <language>en</language>
    <item>
      <title>Debugging BentoFX in MelodyMatrix with Matt Coley, Scenic View, and an Honest Look at AI-Generated Code</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Tue, 21 Apr 2026 10:01:21 +0000</pubDate>
      <link>https://dev.to/fdelporte/debugging-bentofx-in-melodymatrix-with-matt-coley-scenic-view-and-an-honest-look-at-ai-generated-27c9</link>
      <guid>https://dev.to/fdelporte/debugging-bentofx-in-melodymatrix-with-matt-coley-scenic-view-and-an-honest-look-at-ai-generated-27c9</guid>
      <description>&lt;p&gt;There are bugs you can solve by yourself, and bugs where you just need to sit down with someone who knows the internals. This video is in the second category. &lt;a href="https://melodymatrix.rocks/" rel="noopener noreferrer"&gt;MelodyMatrix&lt;/a&gt; uses &lt;a href="https://github.com/Col-E/BentoFX" rel="noopener noreferrer"&gt;BentoFX&lt;/a&gt; for its dockable panel layout. Branches, leaves, tabs on the side, content panels that open and close. It works well until something fights the layout. But I had some visual problems I could not explain, some code that felt more complicated than it should be, and no good explanation for why.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/grwzIWWZMNw"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  When Your Layout Library Misbehaves, Call the Person Who Wrote It
&lt;/h1&gt;

&lt;p&gt;So I asked &lt;a href="https://www.coley.software/" rel="noopener noreferrer"&gt;Matt Coley&lt;/a&gt; if he had time to take a look. Matt is the creator of BentoFX, but he is also known for &lt;a href="https://www.jfx-central.com/showcases/recaf" rel="noopener noreferrer"&gt;Recaf&lt;/a&gt;, a bytecode editor for Java that itself uses BentoFX heavily as its UI framework. That means when Matt looks at a BentoFX integration. He wrote the library and uses it heavily in his own project. If you want the full background on his work, there is an earlier interview: &lt;a href="https://webtechie.be/post/2025-10-30-jfxinaction-matt-coley-recaf-bentofx-treemapfx-glcanvasfx/" rel="noopener noreferrer"&gt;JavaFX In Action #22 with Matt Coley&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What BentoFX Actually Does
&lt;/h2&gt;

&lt;p&gt;BentoFX is a docking and layout library for JavaFX. The core idea is that you have a tree of containers: branches split the space horizontally (or vertically if you rotate them), and leaves hold the actual content. Tabs let you stack multiple panels in one leaf.&lt;/p&gt;

&lt;p&gt;In MelodyMatrix, this maps to a sidebar on the left, a main content area in the middle, and additional panels on the right. It is a clean model when you understand it, but there are some behaviors that are not immediately obvious. Pruning is one of them: when you close a panel, BentoFX removes the empty container and reorganizes the remaining branches. That is usually what you want, but if you are also managing widths or visibility yourself in code, things start to conflict. That was part of my problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenic View: Browser DevTools for JavaFX
&lt;/h2&gt;

&lt;p&gt;This session reminded me that &lt;a href="https://www.jfx-central.com/tools/scenicview" rel="noopener noreferrer"&gt;Scenic View&lt;/a&gt; exists and I should have been using it much earlier.&lt;/p&gt;

&lt;p&gt;If you have done any web development, you know how useful browser inspect tools are. You hover over an element, you can see exactly what CSS is applied, what the padding is, why something is shifted by 12 pixels. Scenic View does the same thing for a running JavaFX application. It attaches to your running application and shows the scene graph live with all the layout properties.&lt;/p&gt;

&lt;p&gt;We pulled it during the video to look at the tab header rotation issue I was having. Instead of guessing which CSS rule was causing the offset, we could see exactly what was happening in the layout tree. Embarrassingly, I had not used it before this session. It should be in your JavaFX debugging toolkit!&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Honest Thoughts on AI-Generated Code
&lt;/h2&gt;

&lt;p&gt;We also spent some time looking at code that had been written or modified by Claude and Copilot. Matt spotted it quickly: the code had the patterns you recognize after reviewing AI-generated output. The rotation fix for the tab headers was one example. The code did technically work, but it was fragile: it used CSS class lookups that would break if BentoFX changed anything internally. Matt's take was pragmatic: if it works now, and you have a way to update it when it breaks, fine. But it is worth knowing that is what you are dealing with.&lt;/p&gt;

&lt;p&gt;The broader cleanup was straightforward once Matt explained how BentoFX manages its own leaf widths. I had added animation and width-tracking code essentially fighting the library. Removing it simplified things considerably and fixed one of the issues in the process. Not all AI-generated code is bad. But a code review from someone who knows the library beats prompting your way through it. This session was a good reminder of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Might Have Found a Bug
&lt;/h2&gt;

&lt;p&gt;BentoFX did something unexpected with divider modes when re-opening a panel that had been closed. Matt looked at his own source and said he suspected something was not right there. It is a 0.x library, but it is actively maintained and used in production in Recaf. Matt's response was immediate: file a ticket with reproduction steps.&lt;/p&gt;

&lt;h1&gt;
  
  
  Timeline
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;00:00 Introduction: Matt Coley, Recaf, BentoFX&lt;/li&gt;
&lt;li&gt;02:19 How BentoFX is used in MelodyMatrix&lt;/li&gt;
&lt;li&gt;04:18 Visual problems with the BentoFX integration&lt;/li&gt;
&lt;li&gt;06:33 A look into the MelodyMatrix code&lt;/li&gt;
&lt;li&gt;09:15 Changing tab position from top to side, and why the project uses Kotlin&lt;/li&gt;
&lt;li&gt;16:25 Using Scenic View to debug a JavaFX layout live&lt;/li&gt;
&lt;li&gt;22:38 How pruning affects visual BentoFX components&lt;/li&gt;
&lt;li&gt;34:53 Cleaning up unneeded code: let BentoFX handle leaf widths, removing animations&lt;/li&gt;
&lt;li&gt;41:33 We probably found a bug in BentoFX, and a look into the BentoFX source&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Links
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2025-10-30-jfxinaction-matt-coley-recaf-bentofx-treemapfx-glcanvasfx/" rel="noopener noreferrer"&gt;JavaFX In Action #22 with Matt Coley, diving into bytecode and JARs with Recaf and JavaFX libraries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Matt Coley: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Col-E" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.coley.software/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jfx-central.com/people/m.coley" rel="noopener noreferrer"&gt;JFX Central&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;JavaFX libraries by Matt: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Col-E/BentoFX" rel="noopener noreferrer"&gt;BentoFX&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Col-E/TreeMapFX" rel="noopener noreferrer"&gt;TreeMapFX&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Col-E/GLCanvasFX" rel="noopener noreferrer"&gt;GLCanvasFX&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;On JFX Central: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.jfx-central.com/libraries/bentofx" rel="noopener noreferrer"&gt;BentoFX&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jfx-central.com/showcases/recaf" rel="noopener noreferrer"&gt;Recaf&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jfx-central.com/libraries/pdffx" rel="noopener noreferrer"&gt;PDFViewFX&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jfx-central.com/tools/scenicview" rel="noopener noreferrer"&gt;Scenic View&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;MelodyMatrix: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://melodymatrix.rocks/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/codewriterbv/melodymatrix-app-views" rel="noopener noreferrer"&gt;Open-source viewers on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>bentofx</category>
      <category>melodymatrix</category>
    </item>
    <item>
      <title>Testing Lottie4J JavaFX Animations in GitHub Actions Without a Display: JavaFX 26 Headless to the Rescue</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Mon, 20 Apr 2026 06:44:35 +0000</pubDate>
      <link>https://dev.to/fdelporte/testing-lottie4j-javafx-animations-in-github-actions-without-a-display-javafx-26-headless-to-the-35ap</link>
      <guid>https://dev.to/fdelporte/testing-lottie4j-javafx-animations-in-github-actions-without-a-display-javafx-26-headless-to-the-35ap</guid>
      <description>&lt;p&gt;When I released &lt;a href="https://lottie4j.com/releases/#2026-03-10-110" rel="noopener noreferrer"&gt;Lottie4J 1.1.0&lt;/a&gt;, I mentioned something a bit embarrassing in the release notes and &lt;a href="https://webtechie.be/post/2026-03-10-new-release-of-lottie4j/" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt;: there was a new unit test to compare the JavaFX player output against a JavaScript reference player, but it "&lt;em&gt;can not run on CI, because it requires a display output&lt;/em&gt;." A TODO. A known limitation. One of those notes you write hoping future-you will figure it out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gluonhq.com/javafx-26-is-now-available/" rel="noopener noreferrer"&gt;JavaFX 26 was released on March 17, 2026&lt;/a&gt; and includes a new headless platform, allowing me to get the test running on GitHub Actions without a display.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Test, and Why It Mattered
&lt;/h2&gt;

&lt;p&gt;The core challenge with Lottie4J is correctness. The Lottie format is complex with a lot of nested data, and my JavaFX renderer has to produce output that matches what a JavaScript player would show. Pixel-perfect is too ambitious, but "is this a close enough match" is a reasonable bar.&lt;/p&gt;

&lt;p&gt;During development, I use a separate application within the Lottie4J project: &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/src/main/java/com/lottie4j/fxfileviewer/LottieFileDebugViewer.java" rel="noopener noreferrer"&gt;LottieFileDebugViewer&lt;/a&gt;. This is a JavaFX application that loads a Lottie file and renders it both with the JavaFX player, and inside a Webview with the official Lottie player. This makes it easy to compare the result and debug differences by diving into the data structure and different layers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqg52ojiopcd7jhhnunb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqg52ojiopcd7jhhnunb.png" alt="Lottie4J debug viewer for local testing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on this debug viewer, I created a unit-test approach with two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/src/test/java/com/lottie4j/fxfileviewer/WebViewScreenshotGenerator.java" rel="noopener noreferrer"&gt;WebViewScreenshotGenerator&lt;/a&gt; that I run once on my developer machine. It loads each animation in a JavaFX WebView using the LottieFiles JavaScript player, and captures screenshots of specific frames. These are the reference images and are committed to the repo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The unit test &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/src/test/java/com/lottie4j/fxfileviewer/CompareFxViewWithWebViewTest.java" rel="noopener noreferrer"&gt;CompareFxViewWithWebViewTest&lt;/a&gt; then renders the same animations with the Lottie4J JavaFX player, takes screenshots at the same frames, and compares pixel data against the references.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The reference images are generated once and committed. The test just checks that the JavaFX output stays consistent with them. If something breaks in the renderer, the test will catch it.&lt;/p&gt;

&lt;p&gt;This was all working fine locally. The problem was GitHub Actions. The CI runner has no display and no graphics stack. So I disabled this test for CI with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@DisabledIfEnvironmentVariable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;named&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CI"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Changed in JavaFX 26
&lt;/h2&gt;

&lt;p&gt;JavaFX 26 added a &lt;a href="https://openjfx.io/highlights/26/" rel="noopener noreferrer"&gt;Headless Platform Prototype&lt;/a&gt; built directly into the &lt;code&gt;javafx.graphics&lt;/code&gt; module. No extra dependencies, no native libraries, no Monocle setup. You pass a single JVM flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-Dglass.platform=headless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it. JavaFX starts up, you get a functional toolkit, you can create scenes, render nodes, take snapshots, and run animations, all without a display attached. The &lt;a href="https://gluonhq.com/" rel="noopener noreferrer"&gt;Gluon team&lt;/a&gt; did the heavy lifting on this for JavaFX 26, and it makes CI testing of JavaFX components much more practical. The flag works the same way as running your application normally. The difference is that there is nothing being drawn to a screen. For testing purposes, that is exactly what you want. It also opens the door to server-side rendering, for example, to generate a snapshot of a UI component without a display.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Catch: JavaFX 26 Requires Java 24
&lt;/h2&gt;

&lt;p&gt;Lottie4J targets &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/pom.xml#L38" rel="noopener noreferrer"&gt;Java 21 and JavaFX 21&lt;/a&gt;. That is the LTS version most projects are still running on. As this version is widely adopted, I don't want to force users of the library to jump to a newer version just because I want fancier test infrastructure. So the main project stays on 21 (for now).&lt;/p&gt;

&lt;p&gt;But JavaFX 26 &lt;a href="https://openjfx.io/highlights/26/" rel="noopener noreferrer"&gt;requires Java 24 or higher&lt;/a&gt; to run. They bumped the compiled bytecode level to &lt;code&gt;--release 24&lt;/code&gt; in this release, so if you try to use it with an older JDK you get an error immediately. This means the test infrastructure has to use a different Java and JavaFX version than the main build. The solution I landed on was a Maven profile in the &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/pom.xml#L50" rel="noopener noreferrer"&gt;root pom.xml&lt;/a&gt; that overrides both version properties and configures the surefire plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;profile&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Activates JavaFX 26 headless windowing for unit tests in CI. --&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Usage: mvn test -Pheadless-tests --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;headless-tests&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;java.version&amp;gt;&lt;/span&gt;25&lt;span class="nt"&gt;&amp;lt;/java.version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;javafx.version&amp;gt;&lt;/span&gt;26&lt;span class="nt"&gt;&amp;lt;/javafx.version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;surefire.argLine.headless&amp;gt;&lt;/span&gt;
            -Dglass.platform=headless --enable-native-access=javafx.graphics
        &lt;span class="nt"&gt;&amp;lt;/surefire.argLine.headless&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-surefire-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.0-M5&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;argLine&amp;gt;&lt;/span&gt;
                        --add-opens com.lottie4j.fxfileviewer/com.lottie4j.fxfileviewer=ALL-UNNAMED
                        -Dglass.platform=headless --enable-native-access=javafx.graphics
                    &lt;span class="nt"&gt;&amp;lt;/argLine&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/profile&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this profile is active, Maven bumps &lt;code&gt;java.version&lt;/code&gt; to 25 and &lt;code&gt;javafx.version&lt;/code&gt; to 26, so the dependency resolution picks up JavaFX 26 for the test classpath while the main source still compiles to Java 21 targets. The surefire plugin then passes two JVM arguments to the test JVM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-Dglass.platform=headless&lt;/code&gt; tells JavaFX to use the new headless glass backend instead of trying to connect to a display.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--enable-native-access=javafx.graphics&lt;/code&gt; is required because the headless platform uses native code paths that the Java module system would otherwise block.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;--add-opens&lt;/code&gt; line gives the test runner access to the fxfileviewer module internals it needs to load and compare the rendered output.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/pom.xml#L95" rel="noopener noreferrer"&gt;fxfileviewer/pom.xml&lt;/a&gt; and &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxplayer/pom.xml#L52" rel="noopener noreferrer"&gt;fxplayer/pom.xml&lt;/a&gt; pick up the overridden &lt;code&gt;javafx.version&lt;/code&gt; property through normal Maven inheritance, so those modules automatically get JavaFX 26 on the test classpath when the profile is active.&lt;/p&gt;

&lt;h2&gt;
  
  
  The GitHub Actions Side
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/.github/workflows/maven.yml#L26" rel="noopener noreferrer"&gt;Maven workflow&lt;/a&gt; sets up the environment with a Java 25 JDK so the JavaFX 26 runtime can load, and invokes Maven with the profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-Pheadless-tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rest of the build still compiles against Java 21 targets, so the library artifact itself is not affected. The profile only kicks in for the test run. The workflow does not need any display setup, no &lt;code&gt;Xvfb&lt;/code&gt;, no &lt;code&gt;DISPLAY&lt;/code&gt; environment variable tweaks. The headless flag handles all of that!&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Actually Tests
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/src/test/java/com/lottie4j/fxfileviewer/CompareFxViewWithWebViewTest.java" rel="noopener noreferrer"&gt;unit test compares screenshots&lt;/a&gt; of Lottie animations rendered by the JavaFX player against the pre-generated reference images from the JavaScript player. It loads a set of known animation files, renders specific frames from each one, takes a snapshot using &lt;code&gt;WritableImage&lt;/code&gt; and &lt;code&gt;SnapshotParameters&lt;/code&gt;, and then does a pixel-level comparison with a configurable tolerance.&lt;/p&gt;

&lt;p&gt;The result is a regression test that runs on every push. If someone changes the rendering logic in a way that visibly breaks an animation, CI will catch it. This is more useful than it sounds, because Lottie rendering involves a lot of layered transformations, easing functions, and shape operations where subtle bugs are easy to introduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Would I Recommend This Pattern?
&lt;/h2&gt;

&lt;p&gt;Yes, with some caveats.&lt;/p&gt;

&lt;p&gt;The version juggling is real work. If you want to use JavaFX 26 headless for testing while keeping your library on an older Java version, you need to be careful about separating the test JVM configuration from the main build. Maven makes this doable but not exactly elegant.&lt;/p&gt;

&lt;p&gt;The reference image approach also requires discipline. The references need to be generated consistently, ideally on a reproducible setup, and you need to think about what tolerance makes sense for your comparisons. Too strict and you get flaky tests. Too loose and you miss real regressions.&lt;/p&gt;

&lt;p&gt;But the payoff is real. The test that I had marked "can not run on CI" now runs on CI. No virtual framebuffer, no Docker tricks, no manual intervention. JavaFX starts up, renders the animations, and the comparison happens cleanly.&lt;/p&gt;

&lt;p&gt;For any library that does visual rendering in JavaFX, this is the kind of testing infrastructure that was genuinely missing before. Good work, OpenJFX contributors!&lt;/p&gt;




&lt;p&gt;Links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lottie4j.com/" rel="noopener noreferrer"&gt;Lottie4J website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lottie4j/lottie4j" rel="noopener noreferrer"&gt;Lottie4J on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openjfx.io/highlights/26/" rel="noopener noreferrer"&gt;JavaFX 26 Highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gluonhq.com/introducing-the-headless-platform-for-javafx/" rel="noopener noreferrer"&gt;Gluon: Introducing the Headless Platform for JavaFX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gluonhq.com/javafx-26-is-now-available/" rel="noopener noreferrer"&gt;Gluon: JavaFX 26 is Now Available&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>lottie</category>
      <category>lottie4j</category>
    </item>
    <item>
      <title>MelodyMatrix V1.0.0 Released: Shipping a JavaFX App with jDeploy, GitHub Actions, and Auto-Update</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Thu, 16 Apr 2026 09:57:28 +0000</pubDate>
      <link>https://dev.to/fdelporte/melodymatrix-v100-released-shipping-a-javafx-app-with-jdeploy-github-actions-and-auto-update-5dba</link>
      <guid>https://dev.to/fdelporte/melodymatrix-v100-released-shipping-a-javafx-app-with-jdeploy-github-actions-and-auto-update-5dba</guid>
      <description>&lt;p&gt;Some side projects take a while to get to a proper release. &lt;a href="https://melodymatrix.rocks/" rel="noopener noreferrer"&gt;MelodyMatrix&lt;/a&gt; is one of those. The app has been downloadable for quite some time thanks to &lt;a href="https://www.jdeploy.com/" rel="noopener noreferrer"&gt;jDeploy&lt;/a&gt;, but there was no official V1.0.0 yet. No tagged release. No moment of "okay, this is it." Just a rolling build on every commit to the &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;That changed now: live, on camera, together with Steve Hannah, the creator of jDeploy.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/_-IL7uHalIU"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is MelodyMatrix?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://melodymatrix.rocks/" rel="noopener noreferrer"&gt;MelodyMatrix&lt;/a&gt; is a JavaFX application for musicians. It connects to MIDI devices, lets you practice and record, and has a set of views that help you understand what you are playing. Those views are open source and available on &lt;a href="https://github.com/codewriterbv/melodymatrix-app-views" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. The full app is free, but has some features that are only available with a license. The download packages are published via &lt;a href="https://github.com/codewriterbv/melodymatrix-app-releases/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Building it has been a long journey. JavaFX, MIDI, and musical theory in one app, keeping it working across Windows, macOS, and Linux, while also building and distributing it automatically from GitHub Actions. That last part is where jDeploy comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is jDeploy?
&lt;/h2&gt;

&lt;p&gt;If you have not heard of jDeploy yet, Steve explains it very well in a few sentences: "&lt;em&gt;Once you finish building a desktop application, you hit a wall. How do you share it? How does your user install it? And when you update it, how do they get the new version without manually downloading and reinstalling?&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;jDeploy solves all of that. It creates native installers for Windows (&lt;code&gt;.exe&lt;/code&gt;), macOS (&lt;code&gt;.dmg&lt;/code&gt;), and Linux, handles auto-update on launch, bundles its own JVM so users do not need Java installed, and uses GitHub Releases as the distribution backend. No Maven Central, no NPM account required. Your GitHub repo is your distribution channel.&lt;/p&gt;

&lt;p&gt;I did a full interview with Steve earlier where he explains the background of the tool: &lt;a href="https://webtechie.be/post/2024-12-12-jfxinaction-steve-hannah-jdeploy/" rel="noopener noreferrer"&gt;JavaFX In Action #12 with Steve Hannah about jDeploy&lt;/a&gt;. Worth watching if you want the full picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Video: Preparing and Triggering the First Release Together
&lt;/h2&gt;

&lt;p&gt;This new video is about an hour long and covers the whole process of getting MelodyMatrix ready for V1.0.0. Steve joined me, and we walked through the project configuration together, fixed a few things in the GitHub Actions workflow, discussed best practices around git tags, and then actually triggered the first release build while the camera was still running.&lt;/p&gt;

&lt;p&gt;Some of the things we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How jDeploy is configured in the MelodyMatrix project, including how JavaFX preview features are enabled.&lt;/li&gt;
&lt;li&gt;npm versus GitHub for the release packages (short version: npm was much easier to get started with than Maven, and Steve modeled the GitHub metadata format on the npm package format).&lt;/li&gt;
&lt;li&gt;Why the Windows installer is an &lt;code&gt;.exe&lt;/code&gt; file and not a zip (user experience: download, click, done).&lt;/li&gt;
&lt;li&gt;How jDeploy manages its own JVM per platform (default is Zulu, with some platform-specific exceptions for Windows ARM and Linux).&lt;/li&gt;
&lt;li&gt;Why Maven is not used for application distribution, and why Steve holds his breath every time he does a Maven deploy.&lt;/li&gt;
&lt;li&gt;How to set the version number for a release without breaking the path to your jar file.&lt;/li&gt;
&lt;li&gt;How to prevent multiple jDeploy workflows from running simultaneously.&lt;/li&gt;
&lt;li&gt;Best practices around git tags, including the capital V versus lowercase v debate.&lt;/li&gt;
&lt;li&gt;Customizing the installer and launcher splash screen with a custom HTML page.&lt;/li&gt;
&lt;li&gt;How jDeploy can use a local build to test the installation before pushing to GitHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And around the 57-minute mark, the release build finished on GitHub Actions and &lt;strong&gt;MelodyMatrix V1.0.0 was live&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why jDeploy, and Why It Is Free
&lt;/h2&gt;

&lt;p&gt;jDeploy is completely free! Steve wants Java desktop apps to be easy to deploy, and any barrier to entry works against that goal. He is working on a paid tier with private repositories and deployment authentication, but the core tool stays free.&lt;/p&gt;

&lt;p&gt;For a solo developer building a side project like MelodyMatrix, that matters. I can push a new version by tagging a commit, and within minutes there is a new installer available for every platform. Users get it automatically on the next launch. No manual distribution, no "please re-download the installer" emails.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Side Note on Lottie4J
&lt;/h2&gt;

&lt;p&gt;While waiting for the GitHub Actions build to finish, Steve mentioned he had been experimenting with adding Lottie animation support to the jDeploy splash screen, and we talked about &lt;a href="https://lottie4j.com/" rel="noopener noreferrer"&gt;Lottie4J&lt;/a&gt; for a bit. That is the kind of thing that happens in a live session. :-) Steve even built a Claude Code skill for creating a custom HTML splash screen with a LottieFiles animation. If you want to try it: &lt;a href="https://github.com/shannah/jdeploy-claude" rel="noopener noreferrer"&gt;jdeploy-claude on GitHub&lt;/a&gt; and the &lt;a href="https://github.com/shannah/jdeploy-claude/tree/main/plugins/jdeploy/skills/custom-launcher-splash" rel="noopener noreferrer"&gt;custom launcher splash screen skill&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Timeline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;00:00 Introduction&lt;/li&gt;
&lt;li&gt;00:48 Who is Steve Hannah and why he created jDeploy to distribute Java applications with automatic updates&lt;/li&gt;
&lt;li&gt;05:42 How Frank uses jDeploy for MelodyMatrix, demo of the application&lt;/li&gt;
&lt;li&gt;07:26 jDeploy configuration in the MelodyMatrix project, how JavaFX preview features are enabled, GitHub Actions&lt;/li&gt;
&lt;li&gt;08:32 How new versions get distributed, npm versus Maven versus GitHub&lt;/li&gt;
&lt;li&gt;10:56 A look into the GitHub Actions flow for MelodyMatrix&lt;/li&gt;
&lt;li&gt;13:38 Why Maven is not used for application distribution&lt;/li&gt;
&lt;li&gt;16:38 Why the Windows installer is an &lt;code&gt;.exe&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;23:13 The JVM runtimes used by a jDeploy application&lt;/li&gt;
&lt;li&gt;26:05 Modifying the splash screen of the installer and application&lt;/li&gt;
&lt;li&gt;28:23 The jDeploy desktop app to configure your project&lt;/li&gt;
&lt;li&gt;31:46 Preparing the MelodyMatrix project for the first release, how to set the release version number, and improving the GitHub workflow&lt;/li&gt;
&lt;li&gt;40:45 Info about the open-source part of the MelodyMatrix project and the struggle between Gradle and Maven&lt;/li&gt;
&lt;li&gt;42:59 Checking the GitHub Actions for the release, and more improvements to prevent multiple simultaneous jDeploy workflows&lt;/li&gt;
&lt;li&gt;45:39 Best practices regarding the use of git tags&lt;/li&gt;
&lt;li&gt;48:42 Starting the build of the first MelodyMatrix release as V1.0.0!&lt;/li&gt;
&lt;li&gt;49:40 While the build process is running on GitHub Actions, experimenting with jDeploy locally&lt;/li&gt;
&lt;li&gt;54:34 Release builds on GitHub Actions are still busy, so another side step to LottieFiles and Lottie4J, and how they could be integrated in the jDeploy splash screen&lt;/li&gt;
&lt;li&gt;57:41 The first release is ready. Installing and trying it...&lt;/li&gt;
&lt;li&gt;01:00:40 jDeploy is free! Steve just wants Java to be easy to deploy&lt;/li&gt;
&lt;li&gt;01:02:31 Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2024-12-12-jfxinaction-steve-hannah-jdeploy/" rel="noopener noreferrer"&gt;JavaFX In Action #12 with Steve Hannah about jDeploy, to distribute your Java app as a native bundle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Steve Hannah: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/sjhannah/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://x.com/shannah78" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://sjhannah.com/blog/" rel="noopener noreferrer"&gt;Personal blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;MelodyMatrix: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://melodymatrix.rocks/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/codewriterbv/melodymatrix-app-views" rel="noopener noreferrer"&gt;Open-source viewers on GitHub&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/codewriterbv/melodymatrix-app-releases/releases" rel="noopener noreferrer"&gt;Download packages on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;jDeploy: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.jdeploy.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/shannah/jdeploy" rel="noopener noreferrer"&gt;Sources on GitHub&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jdeploy.substack.com/" rel="noopener noreferrer"&gt;Newsletter&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jdeploy.substack.com/p/jdeploy-vs-jpackage" rel="noopener noreferrer"&gt;jDeploy vs jpackage&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://jdeploy.substack.com/p/now-you-can-deploy-your-app-as-a" rel="noopener noreferrer"&gt;Now you can deploy your app as a DMG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/shannah/jdeploy-claude" rel="noopener noreferrer"&gt;Claude Code plugin for jDeploy&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/shannah/jdeploy-claude/tree/main/plugins/jdeploy/skills/custom-launcher-splash" rel="noopener noreferrer"&gt;Custom launcher splash screen skill&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Lottie4J: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://lottie4j.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lottie4j/" rel="noopener noreferrer"&gt;Sources on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>kotlin</category>
      <category>melodymatrix</category>
    </item>
    <item>
      <title>Lottie4J 1.2.0: dotLottie Support, Marker Playback, Cropping, and a Big Speed Boost</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Fri, 20 Mar 2026 10:48:55 +0000</pubDate>
      <link>https://dev.to/fdelporte/lottie4j-120-dotlottie-support-marker-playback-cropping-and-a-big-speed-boost-3o06</link>
      <guid>https://dev.to/fdelporte/lottie4j-120-dotlottie-support-marker-playback-cropping-and-a-big-speed-boost-3o06</guid>
      <description>&lt;p&gt;Version 1.2.0 of &lt;a href="https://lottie4j.com" rel="noopener noreferrer"&gt;Lottie4J&lt;/a&gt; is out, and it's again a big release! The headline feature is support for the &lt;code&gt;.lottie&lt;/code&gt; container format, but that's just the start. This release also brings marker-based playback, cropping, adaptive rendering, significant performance improvements, and a lot of core model fixes driven by testing more complex real-world animations.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/9lE6UO8XNpU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  dotLottie File Support
&lt;/h2&gt;

&lt;p&gt;Until now, Lottie4J only supported the plain JSON format (&lt;code&gt;.json&lt;/code&gt;). That's the original Lottie format, but LottieFiles also introduced a newer container format: &lt;code&gt;.lottie&lt;/code&gt;. It's essentially a ZIP archive that can hold one or more animations, embedded images, sounds, and a manifest file that describes the contents.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.lottie&lt;/code&gt; format is a practical improvement: it makes Lottie files smaller and self-contained, bundling images and other assets alongside the animation data instead of relying on external references. Lottie4J now supports loading &lt;code&gt;.lottie&lt;/code&gt; files directly via the core &lt;code&gt;FileLoader&lt;/code&gt;. There are two loading modes available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Load the first animation from a .lottie file (simplest path)&lt;/span&gt;
&lt;span class="nc"&gt;LottieAnimation&lt;/span&gt; &lt;span class="n"&gt;animation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LottieFileLoader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Load the full .lottie container to access the manifest and all animations&lt;/span&gt;
&lt;span class="nc"&gt;DotLottie&lt;/span&gt; &lt;span class="n"&gt;lottie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LottieFileLoader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadDotLottie&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Lottie&lt;/code&gt; object gives you access to the manifest (author, version metadata) and the full list of animations. At the moment, most real-world &lt;code&gt;.lottie&lt;/code&gt; files I found, only bundle a single animation, but the API is ready for multi-animation files when they appear.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Player Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Play Between Markers
&lt;/h3&gt;

&lt;p&gt;Lottie animations can embed named markers. Those are timestamp labels inside the animation JSON that indicate points of interest or looping regions. This is a feature Lottie4J previously parsed but didn't expose in the player. Now it does.&lt;/p&gt;

&lt;p&gt;The new &lt;code&gt;play(startMarker, endMarker)&lt;/code&gt; method makes the player start at frame 1, and then loop between the two named positions in the timeline. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cropping Support
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;LottiePlayer&lt;/code&gt; now supports cropping via &lt;code&gt;crop(top, right, bottom, left)&lt;/code&gt;. This lets you clip the rendered output to a sub-region of the animation canvas, which is handy when you want to embed only part of an animation into a layout without modifying the original file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resizable Player
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;LottiePlayer&lt;/code&gt; is now properly resizable and adjusts its rendering accordingly. Resizing also has a secondary effect: smaller sizes reduce the rendering load, so you can trade size for performance when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Improvements
&lt;/h2&gt;

&lt;p&gt;Rendering speed has improved significantly in this release. The main gains come from reducing the number of rendering passes per frame and adding a caching layer for layer and precomp render metadata, which avoids redundant recalculation on heavy animations.&lt;/p&gt;

&lt;p&gt;The difference is measurable: one test animation that previously played back at around 20–30 FPS now runs at ~50 FPS. A heavier animation that struggled at 11 FPS now reaches ~31 FPS at full size, and scales higher as the player is resized smaller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adaptive Rendering Mode
&lt;/h3&gt;

&lt;p&gt;A new adaptive rendering toggle &lt;code&gt;setAdaptiveOffscreenScalingEnabled(enabled)&lt;/code&gt; trades rendering sharpness for speed. In adaptive mode, JavaFX uses a faster rendering path that can introduce slight blurring on some elements (particularly sharp text or fine detail at certain sizes). In non-adaptive mode, rendering is pixel-precise but slower.&lt;/p&gt;

&lt;p&gt;Which mode works better depends on the animation: simpler animations often look fine in adaptive mode and benefit from the speed, while text-heavy or detail-rich animations are better left in the default mode. The toggle is exposed in both the &lt;code&gt;LottiePlayer&lt;/code&gt; and the file viewers so you can test your specific animations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Model Improvements
&lt;/h2&gt;

&lt;p&gt;A lot of work went into the core library this release, driven by testing more complex real-world Lottie files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Merge and modifier shape support&lt;/strong&gt;: a shape layer feature used in more complex animations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blend mode support&lt;/strong&gt;: layers can now carry blend mode instructions that affect compositing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spatial bezier interpolation&lt;/strong&gt;: position animations now correctly interpolate using bezier curves rather than linear paths, which produces the characteristic easing motion that makes Lottie animations feel polished.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing model fields&lt;/strong&gt;: mask, layer, and animation objects had gaps that caused incorrect rendering on specific files, these are now filled in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved JSON output&lt;/strong&gt;: when recreating a Lottie JSON from the model (write path), value ordering is now more consistent, and the reconstructed file more closely matches the original.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Jackson 3 Upgrade
&lt;/h3&gt;

&lt;p&gt;The core library has been upgraded to Jackson 3. This is a major version bump: the group ID changes from &lt;code&gt;com.fasterxml.jackson&lt;/code&gt; to &lt;code&gt;tools.jackson&lt;/code&gt;, so if you depend on the core directly and also pull in Jackson yourself, you'll want to align on version 3. The upgrade also includes CVE-related dependency updates and follow-up compatibility fixes that came out of the migration.&lt;/p&gt;

&lt;p&gt;Note that &lt;code&gt;jackson-annotations&lt;/code&gt; has not yet moved to the &lt;code&gt;tools.jackson&lt;/code&gt; group ID and remains on its previous coordinates for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debug Tooling Updates
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;LottieFileDebugViewer&lt;/code&gt; has been refactored to extract the duplicated WebView JavaScript bridge code into reusable components. The FX versus JS side-by-side views are improved, and the comparison test has better frame synchronization. A new validation mode tests the player at a resized dimension to verify that rendering holds up under scaling.&lt;/p&gt;

&lt;p&gt;The automated &lt;code&gt;CompareFxViewWithWebViewTest&lt;/code&gt;, which renders both the JavaFX and JavaScript players frame by frame and checks visual similarity, now also uses &lt;code&gt;.lottie&lt;/code&gt; files. &lt;/p&gt;

&lt;h2&gt;
  
  
  Trying It Out
&lt;/h2&gt;

&lt;p&gt;Update your Maven dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Just the core model, no player --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.lottie4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;core&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- JavaFX player --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.lottie4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;fxplayer&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.2.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full list of changes is &lt;a href="https://github.com/lottie4j/lottie4j/compare/v1.1.0...v1.2.0" rel="noopener noreferrer"&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The automated comparison test still can't run on GitHub Actions because it requires a display. JavaFX 26 (released alongside Java 26 this week) includes headless rendering support, which may make it possible to run the visual regression tests on GitHub Actions. That's the next thing to investigate...&lt;/p&gt;

&lt;p&gt;As always: if you run into a Lottie file that doesn't render correctly, please open an issue and attach screenshots. The more real-world files get tested, the better the library gets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://lottie4j.com" rel="noopener noreferrer"&gt;lottie4j.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/lottie4j/lottie4j" rel="noopener noreferrer"&gt;github.com/lottie4j/lottie4j&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Release notes: &lt;a href="https://lottie4j.com/releases/index.html" rel="noopener noreferrer"&gt;lottie4j.com/releases&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>lottie</category>
      <category>animation</category>
    </item>
    <item>
      <title>Lottie4J 1.1.0: Better Rendering, Smarter Debugging, and an animated Lottie4J Logo!</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Tue, 10 Mar 2026 13:24:06 +0000</pubDate>
      <link>https://dev.to/fdelporte/lottie4j-110-better-rendering-smarter-debugging-and-an-animated-lottie4j-logo-21p7</link>
      <guid>https://dev.to/fdelporte/lottie4j-110-better-rendering-smarter-debugging-and-an-animated-lottie4j-logo-21p7</guid>
      <description>&lt;p&gt;Just one week after the first public release of &lt;a href="https://lottie4j.com" rel="noopener noreferrer"&gt;Lottie4J&lt;/a&gt;, the open-source Java library for rendering Lottie animations in JavaFX, version 1.1.0 is already out. And it's a big one!&lt;/p&gt;

&lt;p&gt;A lot happened in that one week. A logo was designed for the project, a Lottie animation was created for that logo (naturally!), and, most importantly, a significant number of rendering improvements landed after testing a much wider range of animation files. That's the reason for the version bump from 1.0.x to 1.1.0: there are some API changes that come with it.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/_zZ1q6zbRgM"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Lottie4J?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://lottiefiles.com/" rel="noopener noreferrer"&gt;LottieFiles&lt;/a&gt; is a JSON-based animation format, originally developed at Airbnb, widely used to play back animations on websites and mobile apps. Players exist for JavaScript, Android, iOS, and more, but a Java/JavaFX player was missing. That's the gap I want to fix with Lottie4J.&lt;/p&gt;

&lt;p&gt;The library is split into two Maven artifacts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core&lt;/strong&gt;: reads and writes Lottie JSON files, useful if you want to process animations without a player.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FXPlayer&lt;/strong&gt;: the JavaFX-based animation player.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find them on &lt;a href="https://central.sonatype.com/namespace/com.lottie4j" rel="noopener noreferrer"&gt;Maven Central&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's New in Lottie4J v1.1.0
&lt;/h2&gt;

&lt;h3&gt;
  
  
  License and API Improvements
&lt;/h3&gt;

&lt;p&gt;The project has switched from GPLv2 to &lt;strong&gt;Apache License V2&lt;/strong&gt;, which makes it much more adoption-friendly for commercial and open-source projects alike. Logging has been migrated to &lt;strong&gt;SLF4J&lt;/strong&gt;, and there have been significant JavaDoc improvements and code restructuring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Many Rendering Fixes in the JavaFX Player
&lt;/h3&gt;

&lt;p&gt;This release is primarily driven by testing more complex real-world Lottie files and fixing what didn't render correctly. Here's what changed in the &lt;code&gt;FXPlayer&lt;/code&gt; module:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correct path closing (fixing gaps in thick borders)&lt;/li&gt;
&lt;li&gt;Better border rendering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track Matte support&lt;/strong&gt; — a key compositing feature in Lottie&lt;/li&gt;
&lt;li&gt;Fix for a layer disappearance at exact keyframe boundaries&lt;/li&gt;
&lt;li&gt;Correct gradient alpha channel parsing for proper transparency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image layer rendering&lt;/strong&gt; — images embedded in Lottie files now display correctly&lt;/li&gt;
&lt;li&gt;Fix for GradientStroke deserialization and color format handling&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Solid color layer rendering&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text rendering&lt;/strong&gt; — text objects in animations now display in the JavaFX player&lt;/li&gt;
&lt;li&gt;Improved animation handling overall&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gaussian Blur effect&lt;/strong&gt; support added&lt;/li&gt;
&lt;li&gt;Fixed layer opacity&lt;/li&gt;
&lt;li&gt;Combined multiple trim paths correctly&lt;/li&gt;
&lt;li&gt;Fixed animations that start later in the timeline&lt;/li&gt;
&lt;li&gt;Fixed stroke style for dotted lines&lt;/li&gt;
&lt;li&gt;Fixed fade transitions for overlapping shapes&lt;/li&gt;
&lt;li&gt;Improved gradient fills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a long list. Animations that were partially broken or visually wrong in 1.0.0 (missing dots, wrong gradients, invisible layers, no text) now render much closer to what the official JavaScript player produces. There are still known open issues: Gaussian blur combined with clipping is tricky in JavaFX, and some complex gradient shapes still differ from the reference player. But the gap has narrowed considerably.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smarter Debug Tooling
&lt;/h3&gt;

&lt;p&gt;One of the most useful additions in this release is the extended &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/src/main/java/com/lottie4j/fxfileviewer/LottieFileDebugViewer.java" rel="noopener noreferrer"&gt;&lt;strong&gt;LottieFileDebugViewer&lt;/strong&gt;&lt;/a&gt;. This tool shows the JavaFX player output side by side with the official JavaScript web player, making it immediately obvious where rendering differs.&lt;/p&gt;

&lt;p&gt;New in this version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screenshot buttons to capture a single frame or all frames at once&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;tile viewer&lt;/strong&gt; that visualizes each layer individually&lt;/li&gt;
&lt;li&gt;The ability to &lt;strong&gt;export a single layer&lt;/strong&gt; as a new Lottie file, so you can isolate and test a specific rendering issue without loading the entire animation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's also a brand-new &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/src/main/java/com/lottie4j/fxfileviewer/LottieFileSimpleViewer.java" rel="noopener noreferrer"&gt;&lt;strong&gt;LottieFileSimpleViewer&lt;/strong&gt;&lt;/a&gt;, a no-frills viewer that just loads a Lottie file and plays it back in a loop using the JavaFX player. Good for quick checks and an example of how you can use the player in your own projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Comparison Testing
&lt;/h3&gt;

&lt;p&gt;Perhaps the most exciting developer tooling addition: a unit test called &lt;a href="https://github.com/lottie4j/lottie4j/blob/main/fxfileviewer/src/test/java/com/lottie4j/fxfileviewer/CompareFxViewWithWebViewTest.java" rel="noopener noreferrer"&gt;&lt;strong&gt;CompareFxViewWithWebViewTest&lt;/strong&gt;&lt;/a&gt; that automates the comparison between the JavaFX player and the JavaScript web player. The test iterates through a list of Lottie files, captures a screenshot every five frames from both players, and compares them for visual similarity. Any frame that differs too much is saved to disk so you can inspect exactly where and how the rendering diverges.&lt;/p&gt;

&lt;p&gt;This makes it much easier to track down rendering regressions and verify improvements. Note that the test requires a display (it can't run headless yet — see &lt;a href="https://github.com/lottie4j/lottie4j/issues/4" rel="noopener noreferrer"&gt;this open issue&lt;/a&gt;), so it won't run on CI for now, but it's extremely useful locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying It Out
&lt;/h2&gt;

&lt;p&gt;Add the Maven dependency for whichever module you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Just the core model, no player --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.lottie4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lottie4j-core&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- JavaFX player --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.lottie4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;lottie4j-fx-player&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full list of changes between 1.0.0 and 1.1.0 is &lt;a href="https://github.com/lottie4j/lottie4j/compare/v1.0.0...v1.1.0" rel="noopener noreferrer"&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The goal isn't to ship a new release every week, but when rendering problems are found in specific animations, the debug tools and automated tests make it much easier to isolate, fix, and verify. If you run into a Lottie file that doesn't render correctly in JavaFX, it can be added to the test suite and investigated.&lt;/p&gt;

&lt;p&gt;The biggest open challenge right now is Gaussian blur combined with clipping, which JavaFX makes particularly difficult. That's a known limitation for now.&lt;/p&gt;

&lt;p&gt;If you're using Lottie4J in a project, I'd love to hear about it! Share what you've built, report rendering differences you find, and follow along for further progress. Contributions and feedback are very welcome.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://lottie4j.com" rel="noopener noreferrer"&gt;lottie4j.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/lottie4j/lottie4j" rel="noopener noreferrer"&gt;github.com/lottie4j/lottie4j&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Release notes: &lt;a href="https://lottie4j.com/releases/index.html" rel="noopener noreferrer"&gt;lottie4j.com/releases&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>lottie</category>
      <category>lottie4j</category>
    </item>
    <item>
      <title>Introducing Lottie4J, a Java(FX) Library to Parse and Play Lottie Animation Files</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Tue, 03 Mar 2026 19:29:54 +0000</pubDate>
      <link>https://dev.to/fdelporte/introducing-lottie4j-a-javafx-library-to-parse-and-play-lottie-animation-files-k4l</link>
      <guid>https://dev.to/fdelporte/introducing-lottie4j-a-javafx-library-to-parse-and-play-lottie-animation-files-k4l</guid>
      <description>&lt;p&gt;I'm proud to present a new JavaFX library: &lt;strong&gt;Lottie4J&lt;/strong&gt;, that brings Lottie animations to JavaFX applications. I first learned about Lottie many years ago when we were developing a mobile app. We used Lottie animations to explain to users how to operate a physical device. The animations made the instructions so much clearer than static images or text alone.&lt;/p&gt;

&lt;p&gt;At the time, I wanted to create a similar experience in JavaFX, but I couldn't find a JavaFX player for the Lottie format. So I decided to build one myself. What I didn't realize then was just how complex this journey would be...&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/6t1O7APENIo"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Lottie?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://lottiefiles.com/" rel="noopener noreferrer"&gt;Lottie&lt;/a&gt; is a JSON-based animation file format created by Airbnb that lets designers export animations from various tools and use them on any platform (mobile, web, desktop) as easily as using static images. It's become the industry standard for vector animations because the files are small, scalable, and can be manipulated programmatically.&lt;/p&gt;

&lt;p&gt;On the Lottie website, you'll find instructions to use After Effects to create animations, but I hope you know there are way better, less expensive alternatives to Adobe applications... I stepped away from Adobe many years ago and advise you to do the same. Check &lt;a href="https://www.blackmagicdesign.com/products/davinciresolve" rel="noopener noreferrer"&gt;DaVinci Resolve&lt;/a&gt; for video editing and &lt;a href="https://www.affinity.studio/" rel="noopener noreferrer"&gt;Affinity&lt;/a&gt; for drawing applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Complexity of Lottie
&lt;/h3&gt;

&lt;p&gt;You see, the Lottie format, although JSON-based, is incredibly complex and hard to understand. The JSON uses cryptic abbreviated property names like &lt;code&gt;nm&lt;/code&gt; for name, &lt;code&gt;fr&lt;/code&gt; for frames per second, &lt;code&gt;ddd&lt;/code&gt; for "has 3D layers".&lt;/p&gt;

&lt;p&gt;The specification uses nested structures for layers, shapes, effects, and animations. Understanding what each property does and how they interact requires diving deep into the documentation and lots of trial and error experiments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lottie4J Project
&lt;/h2&gt;

&lt;p&gt;I created Lottie4J as a multi-module Maven project. I started working on this already in 2022, but only now, thanks to the evolutions happening with Claude.ai, I could dive into the Lottie format deep enough to understand it and handle the data correctly to get it visualized and animated in the correct way. Turns out my data model parsing was already correct. Also my first JavaFX rendering worked well, but with some changes in how the nested data structures are handled, I'm now convinced the library is ready to be released as version 1.0.0.'&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;Lottie4J is organized into three main modules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Core&lt;/strong&gt;: The Java objects representing the Lottie data model and file loading&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FXPlayer&lt;/strong&gt;: A JavaFX component that actually plays the animations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FXFileViewer&lt;/strong&gt;: A demo application that shows animations and visualizes their structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpm6jh3lldpowm4b3zcxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpm6jh3lldpowm4b3zcxf.png" alt="Lottie4J test application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Sense of the JSON
&lt;/h2&gt;

&lt;p&gt;One of my goals was to make the cryptic Lottie format more understandable. In the Animation class in the core library, each cryptic JSON property is mapped to a clear, descriptive name. &lt;code&gt;@JsonProperty("fr")&lt;/code&gt; becomes &lt;code&gt;framesPerSecond&lt;/code&gt;, &lt;code&gt;@JsonProperty("ip")&lt;/code&gt; becomes &lt;code&gt;inPoint&lt;/code&gt;. Java objects use human-readable names, making the code self-documenting and much easier to work with.&lt;/p&gt;

&lt;p&gt;But I went even further. The &lt;strong&gt;fxfileviewer&lt;/strong&gt; application includes a tree visualizer that lets you explore the structure of any Lottie file in an easy view. You can see exactly what's inside your animation - the layers, shapes, properties, and how they're nested. This was invaluable for understanding the format and debugging animations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Animations
&lt;/h3&gt;

&lt;p&gt;I've included several test animations in the project to showcase the capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;java_duke_flip.json&lt;/strong&gt; - The Java Duke mascot doing a flip animation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;loading.json&lt;/strong&gt; - A loading spinner animation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sandy_loading.json&lt;/strong&gt; - A particularly tricky one testing complex nested transformations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;timeline_animation.json&lt;/strong&gt; - A timeline animation showing how multiple elements can be choreographed together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While an animation plays, you can see the complete structure in the tree view - every layer, every shape, every animated property.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Lottie4J
&lt;/h2&gt;

&lt;p&gt;Using Lottie4J in your JavaFX application is straightforward. Import the fxplayer-dependency in your pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.lottie4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;fxplayer&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the animation with this minimal code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;LottiePlayer&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LottiePlayer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"path/to/animation.json"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getChildren&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load your Lottie JSON file, create a LottiePlayer component, add it to your scene or parent component. That's it! The player handles all the complexity of parsing the animation and rendering it frame by frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous Evolution
&lt;/h2&gt;

&lt;p&gt;The Lottie format is constantly evolving with new features and capabilities. There's always more to implement, more edge cases to handle, more animations to test. But that's what makes this project interesting - it's a continuous learning experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;If you're working with JavaFX and want to add beautiful, lightweight animations to your applications, check out Lottie4J. All the code is open source and available on &lt;a href="https://github.com/lottie4j/lottie4j" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. You'll find more documentation and examples on &lt;a href="https://lottie4j.com" rel="noopener noreferrer"&gt;lottie4j.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please let me know how you use the library and share your results. I'm sure not all animations will already render completely the same as with the more mature players, so if you find differences, it would be very nice if you could isolate the problem and share the json file with a clear description of the issue in a ticket in the GitHub repository.&lt;/p&gt;

&lt;p&gt;Happy animating!&lt;/p&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>lottie</category>
      <category>animation</category>
    </item>
    <item>
      <title>I Benchmarked Java on Single-Board Computers: Orange Pi 5 Ultra and Raspberry Pi 5 Lead the Pack</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Tue, 24 Feb 2026 09:49:32 +0000</pubDate>
      <link>https://dev.to/fdelporte/i-benchmarked-java-on-single-board-computers-orange-pi-5-ultra-and-raspberry-pi-5-lead-the-pack-33oh</link>
      <guid>https://dev.to/fdelporte/i-benchmarked-java-on-single-board-computers-orange-pi-5-ultra-and-raspberry-pi-5-lead-the-pack-33oh</guid>
      <description>&lt;p&gt;In my "Java on Single Board Computers" series, I already published several posts and videos in which I unpack the board, connect it for the first time, and try to install and run some simple Java code. In this post, I want to share some benchmarks of Java on these boards to get a better idea of the performance we can expect from Java on these platforms.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/efLS8pBtqZ0"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Already published in this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2025-11-25-first-test-lattepanda-iota-with-ubuntu-and-java/" rel="noopener noreferrer"&gt;First Experiments with Java on the LattePanda IOTA: An Alternative to Raspberry Pi?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2026-01-12-first-test-orangepi-java/" rel="noopener noreferrer"&gt;First Test of Java on the Orange Pi (ARM and RISC-V)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2026-01-16-first-test-visionfive-java/" rel="noopener noreferrer"&gt;First Test of Java on the StarFive VisionFive 2 Lite (RISC-V)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2026-02-10-first-test-beagleboard-java/" rel="noopener noreferrer"&gt;First Test of Java on BeagleBoards (ARM and RISC-V)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2026-02-13-java-25-runs-on-riscv-beagleboard-beaglev-fire/" rel="noopener noreferrer"&gt;I Got Java 25 Running on the RISC-V BeagleBoard BeagleV-Fire&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2026-01-14-3d-print-sbc-stack/" rel="noopener noreferrer"&gt;Keeping Single-Board Computers Organized with a 3D Printed Stack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benchmark Tool
&lt;/h2&gt;

&lt;p&gt;To make the benchmark testing as easy as possible, I created a simple tool (written in Java of course!) that can be executed with &lt;a href="https://www.jbang.dev/" rel="noopener noreferrer"&gt;JBang&lt;/a&gt;. The complete project is available on GitHub at &lt;a href="https://github.com/FDelporte/sbc-java-comparison" rel="noopener noreferrer"&gt;github.com/FDelporte/sbc-java-comparison&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The project consists of two main parts: a runner and a summarizer.&lt;/p&gt;

&lt;h3&gt;
  
  
  BenchmarkRunner.java - The User Tool
&lt;/h3&gt;

&lt;p&gt;This is the tool you run on your single-board computer. It's a JBang script that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Detects system information&lt;/strong&gt;: This uses the &lt;a href="https://github.com/oshi/oshi" rel="noopener noreferrer"&gt;OSHI library&lt;/a&gt; to gather details about the board, CPU, memory, JVM, and operating system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Downloads the Renaissance benchmark suite&lt;/strong&gt;: Automatically fetches the &lt;a href="https://renaissance.dev/" rel="noopener noreferrer"&gt;Renaissance Suite&lt;/a&gt; if it's not already cached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runs the benchmarks&lt;/strong&gt;: Executes each benchmark three times and calculates the average score.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saves results locally&lt;/strong&gt;: Creates a JSON file with all the benchmark data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uploads to GitHub&lt;/strong&gt;: Optionally, the results file can be pushed to the repository via the GitHub API for inclusion in the comparison.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can run it directly from GitHub with a single command, after setting up your GitHub API token and the repository details (if needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;ghp_yourtoken&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BENCH_GITHUB_OWNER&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;your_github_account&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BENCH_GITHUB_REPO&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;your_fork&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BENCH_GITHUB_BRANCH&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;your_branch&lt;span class="o"&gt;}&lt;/span&gt;

jbang https://github.com/FDelporte/sbc-java-comparison/raw/main/BenchmarkRunner.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to run it without uploading results, add the &lt;code&gt;--skip-push&lt;/code&gt; flag. And if your board has memory constraints, you can limit the heap size with &lt;code&gt;--heap-limit 768m&lt;/code&gt; for example.&lt;/p&gt;

&lt;p&gt;The script generates a report that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"systemInfo"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"boardInfo"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RK3588 OPi 5 Ultra"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cpuInfo"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RK3588 OPi 5 Ultra"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"identifier"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ARM Family 8 Model 0xd0b Stepping r2p0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"logicalCores"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"memoryInfo"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"totalMB"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15964&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jvmInfo"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"25.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"osInfo"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"family"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ubuntu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"results"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; 
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"akka-uct"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;17702.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"unit"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Actor-based concurrency. Interesting for comparing how well thread scheduling works across ARM, x86, and RISC-V kernels."&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-02-18T10:47:46.198052372Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SummarizeReports.java - The Automation Tool
&lt;/h3&gt;

&lt;p&gt;This tool runs automatically via a GitHub Action whenever a new benchmark result gets added to the repository. This tool:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Loads all files from the &lt;code&gt;report&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Finds the unique platforms by CPU model and keeps only the most recent result for each unique CPU.&lt;/li&gt;
&lt;li&gt;Generates &lt;code&gt;summary.json&lt;/code&gt;, a consolidated file in the &lt;code&gt;data&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This summary file is then used by the web dashboard to visualize all the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  About The Renaissance Benchmark Suite
&lt;/h2&gt;

&lt;p&gt;Rather than creating benchmarks from scratch, I chose to use the &lt;a href="https://renaissance.dev/" rel="noopener noreferrer"&gt;Renaissance Benchmark Suite&lt;/a&gt;, an open-source project designed specifically for JVM performance evaluation. Renaissance is maintained by researchers and includes a variety of real-world workloads that stress different aspects of the JVM and hardware.&lt;/p&gt;

&lt;p&gt;The suite includes benchmarks for parallel computing, functional programming, machine learning, and more. I selected seven benchmarks that are related to the restrictions of single-board computers. I also found out that the &lt;code&gt;scrabble&lt;/code&gt; benchmark can't run with Java 25, so it's not included.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;akka-uct&lt;/strong&gt;: Actor-based concurrency, tests thread scheduling across different architectures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fj-kmeans&lt;/strong&gt;: Fork/join parallelism with K-Means clustering, stresses CPU and multi-core utilization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;scala-kmeans&lt;/strong&gt;: Single-threaded K-Means in Scala, provides a single-core performance baseline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;future-genetic&lt;/strong&gt;: Genetic algorithm using futures, exercises the thread pool and garbage collector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mnemonics&lt;/strong&gt;: Serial JDK Streams, baseline for stream processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;par-mnemonics&lt;/strong&gt;: Parallel JDK Streams, reveals how well different architectures handle parallelism.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;db-shootout&lt;/strong&gt;: In-memory databases, tests memory bandwidth and subsystem performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I specifically avoided the Apache Spark benchmarks from Renaissance, as they're very memory-hungry and designed for multicore server machines. They would either crash with OutOfMemoryErrors or take forever on these constrained boards.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;p&gt;Based on the automatically generated &lt;code&gt;summary.json&lt;/code&gt; and other configuration files in the &lt;a href="https://github.com/FDelporte/sbc-java-comparison/tree/main/data" rel="noopener noreferrer"&gt;repository's data directory&lt;/a&gt;, I created (with a lot of help of &lt;a href="https://claude.ai" rel="noopener noreferrer"&gt;Claude.ai&lt;/a&gt;...) an interactive dashboard to visualize all the results. You can explore it yourself at &lt;a href="https://webtechie.be/sbc/" rel="noopener noreferrer"&gt;webtechie.be/sbc/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Important note: I ran the tests on the default Ubuntu system provided by the manufacturer of the board, after doing an update/upgrade and installation of OpenJDK 25 and JBang. The runner itself also uses some resources of the board, so this influences the numbers, but the same approach has been used on all boards to have a similar comparison.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dashboard
&lt;/h3&gt;

&lt;p&gt;The "&lt;a href="http://vanilla-js.com/" rel="noopener noreferrer"&gt;Vanilla JavaScript&lt;/a&gt;" (= no libraries, just HTML/CSS/JS) dashboard presents the benchmark results in an easy-to-understand format. For each board, you can see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System information: Board model, CPU details, memory, Java version, and operating system.&lt;/li&gt;
&lt;li&gt;Individual benchmark scores for each of the seven tests.&lt;/li&gt;
&lt;li&gt;Visual comparisons across all tested boards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dashboard pulls the latest summary and other data files from the repository, so it's a living comparison that grows as more test reports become available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmc884lyjg0fnz0h3xpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmc884lyjg0fnz0h3xpw.png" alt="Overall results of the SBCs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are screenshots from a first test round. Check the &lt;a href="https://webtechie.be/sbc/" rel="noopener noreferrer"&gt;actual last status at webtechie.be/sbc/&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing the Results
&lt;/h3&gt;

&lt;p&gt;Some general remarks about the charts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The overview chart at the top gives the best board (based on your selection) a score of 100% (best), and the other boards are compared to it.&lt;/li&gt;
&lt;li&gt;For the other charts, per benchmark, the lower scores are better. All benchmarks measure execution time in milliseconds, so lower numbers indicate faster performance.&lt;/li&gt;
&lt;li&gt;Because of the limited amount of memory on the BeagleV-Fire, the benchmarks were executed with &lt;code&gt;--heap-limit 768m&lt;/code&gt; on this board to avoid JVM crashes. This is also a factor leading to the lower scores for this board.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Performance Leaders
&lt;/h4&gt;

&lt;p&gt;Not surprisingly, my &lt;strong&gt;Apple M2&lt;/strong&gt; workstation dominates the charts with the fastest scores across all benchmarks. This is expected, it's a high-end desktop processor with 12 cores and significantly more power budget than any single-board computer. The &lt;strong&gt;LattePanda IOTA&lt;/strong&gt; with its &lt;strong&gt;Intel N150&lt;/strong&gt; x86 processor also performs exceptionally well, coming in second place on most tests.&lt;/p&gt;

&lt;p&gt;The LattePanda IOTA deserves special attention here. While I initially excluded it from the "true" single-board computer competition, the pricing actually deserves reconsideration. At 110€, it's comparable to a &lt;strong&gt;Raspberry Pi 5 with additional M.2 expansion&lt;/strong&gt;. The IOTA comes pre-equipped with an M.2 slot for NVMe storage expansion, full-size HDMI, three USB ports, and GPIO headers, all integrated into one board. However, it does require active cooling (the "do not operate without a heatsink" warning is serious), has a slightly larger form factor than traditional Raspberry Pi boards, and demands more power. It's still more of a &lt;strong&gt;compact x86 PC than a Raspberry Pi competitor&lt;/strong&gt;, but for users who specifically need x86 compatibility (running existing x86 applications, Windows support if needed, or specific libraries), it offers exceptional performance for the price. &lt;/p&gt;

&lt;p&gt;For traditional single-board computer use cases like IoT, robotics, GPIO-heavy projects, etc. the ARM-based boards remain the better choice. Definitely the GPIO headers have an advantage on the Raspberry Pi, Orange Pi, and similar boards. I tried the GPIOs on the LattePanda IOTA, and found out that they are exposed by a RP2040 co-processor which connects to the Intel CPU via USB. A strange approach which will be hard to use with the &lt;a href="https://www.pi4j.com/" rel="noopener noreferrer"&gt;Pi4J library&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Real Single-Board Computer Competition
&lt;/h4&gt;

&lt;p&gt;Among the boards that fit the traditional SBC form factor (Raspberry Pi-sized, passive or small fan cooling, under $200), the results tell a more nuanced story:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orange Pi 5 Ultra&lt;/strong&gt; (ARM RK3588, 8 cores) shows the best results in most of the tests, particularly on multithreaded workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raspberry Pi 5&lt;/strong&gt; (ARM Cortex-A76, 4 cores @ 2.4GHz) delivers solid, consistent performance across all benchmarks, very close to the Orange Pi 5 Ultra.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raspberry Pi 4&lt;/strong&gt; (ARM Cortex-A72, 4 cores @ 1.8GHz) still performs admirably despite being an older generation.&lt;/li&gt;
&lt;li&gt;All others show significantly lower performance, which is expected given their lower core counts and less powerful CPUs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  RISC-V Performance
&lt;/h4&gt;

&lt;p&gt;The RISC-V boards present an interesting case. The &lt;strong&gt;Orange Pi RV2&lt;/strong&gt;, &lt;strong&gt;BeagleV-Fire&lt;/strong&gt;, and &lt;strong&gt;StarFive VisionFive 2 Lite&lt;/strong&gt; show that RISC-V is absolutely viable for running Java applications, though performance still lags behind ARM equivalents. This is expected given that RISC-V is a newer architecture with less mature tooling and optimization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selecting a Winner
&lt;/h3&gt;

&lt;p&gt;If I had to pick a winner from the "true" single-board computers (excluding my Apple workstation and the LattePanda IOTA), the &lt;strong&gt;OrangePi 5 Ultra&lt;/strong&gt; comes out on top, but the &lt;strong&gt;Raspberry Pi 5&lt;/strong&gt; is a very close second. These boards offer the best combination of performance and price. Raspberry Pi has the added advantage of a big ecosystem support, and ease of use with the &lt;a href="https://www.raspberrypi.com/software/" rel="noopener noreferrer"&gt;Imager Tool&lt;/a&gt;. Orange Pi can still learn a lot from the extensive documentation, and huge library of compatible accessories and software that is available for Raspberry Pi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I wanted to run benchmarks on multiple boards but needed a solution to do this as quickly and easily as possible. After all, this is a pet project for me. I got the boards for free, but comparing them is a personal challenge in my "free" time... With the current setup with the two scripts, I found a solution which is fast to execute. I only need access from my work PC, copy the GitHub token and JBang command, and let the test run in the background. The GitHub Action then automatically pushes the results to the repository and updates the dashboard. So, goal achieved! :-)&lt;/p&gt;

&lt;p&gt;The results confirm: &lt;strong&gt;Java runs without problems on all these platforms, from ARM to x86 to RISC-V&lt;/strong&gt;! Of course, there are performance differences between architectures and specific boards, but every single one of the tested devices can run real-world Java applications with a good performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try It Yourself!
&lt;/h3&gt;

&lt;p&gt;I encourage you to run the benchmark on your own boards and contribute the results! The process is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make sure you have Java 25 and JBang installed&lt;/span&gt;
jbang https://github.com/FDelporte/sbc-java-comparison/raw/main/BenchmarkRunner.java  &lt;span class="nt"&gt;--skip-push&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want your results added to the public dashboard, follow the instructions in the &lt;a href="https://github.com/FDelporte/sbc-java-comparison" rel="noopener noreferrer"&gt;repository README&lt;/a&gt; to set up GitHub API access and submit your results.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;This is just the beginning! I also received two Banana Pi boards I still need to unpack and test. And it would also be great to add a benchmark for JavaFX performance, but that will exclude RISC-V as there is no JavaFX port for it (yet?). And, of course, I really want to get started with exploring &lt;a href="https://www.pi4j.com/" rel="noopener noreferrer"&gt;Pi4J&lt;/a&gt; on all these boards and see how it compares to the GPIO use of the Raspberry Pi.&lt;/p&gt;

&lt;p&gt;If you have suggestions for additional benchmarks or want to see specific boards tested, let me know in the comments or reach out on &lt;a href="https://foojay.social/@frankdelporte" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt;, &lt;a href="https://bsky.app/profile/frankdelporte.be" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt;, or my &lt;a href="https://www.youtube.com/@FrankDelporte/community" rel="noopener noreferrer"&gt;YouTube community&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>java</category>
      <category>benchmark</category>
      <category>riscv</category>
      <category>arm</category>
    </item>
    <item>
      <title>JavaFX In Action #26 with Helal Anwar about GradedAttendance to Organize Class Rooms, Students, Teachers, and Lessons</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Thu, 19 Feb 2026 08:13:40 +0000</pubDate>
      <link>https://dev.to/fdelporte/javafx-in-action-26-with-helal-anwar-about-gradedattendance-to-organize-class-rooms-students-2j7f</link>
      <guid>https://dev.to/fdelporte/javafx-in-action-26-with-helal-anwar-about-gradedattendance-to-organize-class-rooms-students-2j7f</guid>
      <description>&lt;p&gt;Every week, I collect a list of posts, social messages, videos, etc. related to JavaFX on the &lt;a href="https://www.jfx-central.com/links" rel="noopener noreferrer"&gt;JFX Central Links Of The Week&lt;/a&gt;. One of the regular "appearances" is Helal Anwar, who is building impressive educational tools with JavaFX. In this interview, we discuss his GradedAttendance application and other JavaFX projects he's working on.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/pbQZK68tplA"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  About Helal
&lt;/h2&gt;

&lt;p&gt;Helal Anwar is an undergraduate student, passionate about creating practical solutions for educational environments. His philosophy on programming is clear: "Programming isn't about what you know; it's about what you can figure out." With experience in both teaching and software development, he has identified common classroom management challenges and developed JavaFX-based tools to address them.&lt;/p&gt;

&lt;p&gt;He is an active contributor to the JavaFX community, regularly sharing his projects and insights on social media, making him a frequent feature in the &lt;a href="https://www.jfx-central.com/links/" rel="noopener noreferrer"&gt;JavaFX Links of the Week on JFX Central&lt;/a&gt;. Beyond GradedAttendance, he has created several other JavaFX applications, including a Quiz App, Calculator, Media Player, and Sliding Puzzle game.&lt;/p&gt;

&lt;p&gt;You can find him and his work on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/helal-anwar-94571016b/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/24F3004969" rel="noopener noreferrer"&gt;GitHub profile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@helalanwar2561" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/24F3004969/QuizTime" rel="noopener noreferrer"&gt;Quiz App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/24F3004969/Calculator" rel="noopener noreferrer"&gt;Calculator App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/24F3004969/Finger_Player" rel="noopener noreferrer"&gt;Media Player&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/24F3004969/SlidingPuzzle" rel="noopener noreferrer"&gt;Sliding Puzzle&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About GradedAttendance
&lt;/h2&gt;

&lt;p&gt;GradedAttendance is a desktop application built with JavaFX to manage student attendance and classroom activities in educational settings. The application demonstrates several key advantages of using JavaFX for educational tools, making it a perfect solution for teachers and educational institutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why JavaFX for Educational Tools
&lt;/h3&gt;

&lt;p&gt;The choice of JavaFX as the development platform was deliberate and well-justified. Unlike web-based solutions, a desktop application built with JavaFX offers several critical advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Offline functionality&lt;/strong&gt;: The app works without an internet connection, which is crucial in educational environments where connectivity might be unreliable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data privacy&lt;/strong&gt;: All data is processed and stored locally, ensuring student information remains secure and cannot be uploaded to external services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Desktop applications provide better performance and responsiveness compared to web-based alternatives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stability&lt;/strong&gt;: Java and JavaFX are mature, stable platforms with extensive documentation and examples that remain relevant over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Technical Implementation and Design
&lt;/h3&gt;

&lt;p&gt;The application showcases several JavaFX features and best practices. Helal is a big fan of &lt;a href="https://gluonhq.com/products/scene-builder/" rel="noopener noreferrer"&gt;Scene Builder&lt;/a&gt; for designing user interfaces, which allows for visual layout design and rapid prototyping. The application takes full advantage of JavaFX's rendering capabilities to create a polished, professional interface that renders beautifully within the JavaFX framework.&lt;/p&gt;

&lt;p&gt;For data storage, GradedAttendance uses &lt;a href="https://sqlite.org/index.html" rel="noopener noreferrer"&gt;SQLite&lt;/a&gt;. Despite its name suggesting "light," SQLite provides a full-featured database that's perfect for desktop applications, handling all data storage needs efficiently while keeping everything local to the user's machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Open Source Philosophy
&lt;/h3&gt;

&lt;p&gt;The project is open source, shared with the community not necessarily to gather contributors (though they're welcome), but primarily to help others who might face similar challenges. Helal's philosophy is simple: when he couldn't find a solution to his problem, he created one and shared it so others wouldn't have to start from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning JavaFX with Modern Tools
&lt;/h3&gt;

&lt;p&gt;An interesting point raised during the interview is the value of JavaFX's maturity when it comes to learning and problem-solving. Tools like ChatGPT and other AI assistants have been trained on extensive JavaFX documentation and examples accumulated over years. This means that even older examples and tutorials remain relevant and useful for learning JavaFX, making it easier for newcomers to get started. The stability of the platform ensures that knowledge gained years ago is still applicable today.&lt;/p&gt;

&lt;h3&gt;
  
  
  The State of JavaFX in Education
&lt;/h3&gt;

&lt;p&gt;The interview touched an important issue: many educational institutions still teach older Java GUI frameworks like Swing, despite JavaFX being a more modern and capable alternative. As Helal pointed out, when he was taught Java in college, they were still teaching Swing. His question was simple but important: "Why are you teaching Swing? There's a better thing available. Why not teach that?" This highlights the need for greater awareness of JavaFX's capabilities in academic settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Looking at the Code
&lt;/h3&gt;

&lt;p&gt;When discussing what he's most proud of in the codebase, Helal mentioned the integration of various libraries that make the application powerful yet maintainable. The use of AtlantaFX for theming, CalendarFX for scheduling features, and Ikonli for icons creates a modern, professional application. The application also incorporates JLatexMath for rendering mathematical formulas, which is particularly useful in educational contexts, and SQLite JDBC for robust database connectivity.&lt;/p&gt;

&lt;p&gt;You can find more information about GradedAttendance on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/24F3004969/GradedAttendance" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used libraries and other links from the video:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/mkpaz/atlantafx" rel="noopener noreferrer"&gt;AtlantaFX&lt;/a&gt;: Modern JavaFX theme&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dlsc-software-consulting-gmbh/CalendarFX" rel="noopener noreferrer"&gt;CalendarFX&lt;/a&gt;: Calendar and scheduling components&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kordamp/ikonli" rel="noopener noreferrer"&gt;Ikonli&lt;/a&gt;: Icon packs for Java applications&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/opencollab/jlatexmath" rel="noopener noreferrer"&gt;JLatexMath&lt;/a&gt;: LaTeX rendering for Java&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/xerial/sqlite-jdbc" rel="noopener noreferrer"&gt;SQLite JDBC&lt;/a&gt;: JDBC driver for SQLite&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/emilk/egui" rel="noopener noreferrer"&gt;egui&lt;/a&gt;: Immediate mode GUI in Rust library&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/linebender/xilem" rel="noopener noreferrer"&gt;Xilem&lt;/a&gt;: Experimental Rust native UI framework&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://melodymatrix.rocks/" rel="noopener noreferrer"&gt;MelodyMatrix&lt;/a&gt;: JavaFX application to visualize music&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tv270sr0omcbmp9bnqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tv270sr0omcbmp9bnqj.png" alt="Screenshot GradedAttendance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Video content
&lt;/h2&gt;

&lt;p&gt;00:00 Who is Helal&lt;/p&gt;

&lt;p&gt;00:57 How GradedAttendance started (thanks to SceneBuilder)&lt;/p&gt;

&lt;p&gt;02:29 About GradedAttendance and demo of the application&lt;/p&gt;

&lt;p&gt;06:47 Why JavaFX and not a browser application?&lt;/p&gt;

&lt;p&gt;07:40 Challenges during development (database)&lt;/p&gt;

&lt;p&gt;10:05 Goal of making it as an open-source project&lt;/p&gt;

&lt;p&gt;11:25 Other projects Helal worked on&lt;/p&gt;

&lt;p&gt;13:04 Learning from books and chat systems&lt;/p&gt;

&lt;p&gt;13:45 How GradedAttendance became bigger thanks to MelodyMatrix and AtlantaFX&lt;/p&gt;

&lt;p&gt;14:59 Helal wants to see JavaFX more used in programming classes&lt;/p&gt;

&lt;p&gt;15:45 Thanks to the many Java library creators!&lt;/p&gt;

&lt;h2&gt;
  
  
  More JFX In Action...
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://webtechie.be/tags/jfx-in-action/" rel="noopener noreferrer"&gt;Click here for more posts with JFX In Action videos&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>interview</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Got Java 25 Running on the RISC-V BeagleBoard BeagleV-Fire</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Fri, 13 Feb 2026 13:02:35 +0000</pubDate>
      <link>https://dev.to/fdelporte/i-got-java-25-running-on-the-risc-v-beagleboard-beaglev-fire-202e</link>
      <guid>https://dev.to/fdelporte/i-got-java-25-running-on-the-risc-v-beagleboard-beaglev-fire-202e</guid>
      <description>&lt;p&gt;After my initial struggles with the BeagleV-Fire in a &lt;a href="https://webtechie.be/post/2026-02-10-first-test-beagleboard-java/" rel="noopener noreferrer"&gt;previous video&lt;/a&gt;, I succeeded in getting Java 25 running on  RISC-V-powered BeagleV-Fire! Let me walk you through the journey and the steps I took to make it work.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/p08u_g7hFwE"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;In my earlier &lt;a href="https://webtechie.be/post/2026-02-10-first-test-beagleboard-java/" rel="noopener noreferrer"&gt;blog post and video about several BeagleBoards&lt;/a&gt;, I demonstrated that Java, JavaFX, and even Pi4J worked perfectly. That's expected, since ARM processors, like those in Raspberry Pi boards, have run Java reliably for years.&lt;/p&gt;

&lt;p&gt;However, the BeagleV-Fire with its RISC-V processor presented a different story. The board came pre-installed with Ubuntu 23, and I hit a wall immediately. The apt repositories were outdated and no longer available, making it impossible to install Java or update the system to a newer Ubuntu version.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: BeagleBoard Imaging Utility
&lt;/h2&gt;

&lt;p&gt;The key to solving this problem was updating the operating system using the &lt;a href="https://www.beagleboard.org/bb-imager" rel="noopener noreferrer"&gt;BeagleBoard Imaging Utility&lt;/a&gt;. Unlike Raspberry Pi boards that use SD cards, the BeagleV-Fire has eMMC storage with the operating system pre-installed. This means you need to replace the board's existing OS with a newer version. The process took about half an hour in real time (though I've edited the video down significantly), including updating the system and installing all the latest dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serial Connection Setup
&lt;/h3&gt;

&lt;p&gt;As described on the &lt;a href="https://docs.beagle.cc/boards/beaglev/fire/02-quick-start.html" rel="noopener noreferrer"&gt;BeagleBoard Documentation &amp;gt; Boards &amp;gt; BeagleV-Fire &amp;gt; Quick Start&lt;/a&gt;, you need a serial connection to see what the board is doing and interrupt it at the right moment to make it accessible from the Imaging Utility. I used a &lt;a href="https://www.amazon.com.be/dp/B083HVM7VZ?ref=ppx_yo2ov_dt_b_fed_asin_title" rel="noopener noreferrer"&gt;DSD TECH USB to TTL Serial Cable&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmk0scheti1lj50ocwdv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmk0scheti1lj50ocwdv0.png" alt="Serial connection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You also need a USB-to-USB cable to connect the board to your computer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failed With macOS
&lt;/h3&gt;

&lt;p&gt;I initially tried connecting the board to my Apple workstation via USB. Despite the USB-to-serial cable being detected, I ran into issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% ls -l /dev/tty.*
crw-rw-rw-  1 root  wheel  0x9000002 Jan 19 09:15 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel  0x9000000 Jan 19 09:13 /dev/tty.debug-console
crw-rw-rw-  1 root  wheel  0x9000004 Feb 10 16:19 /dev/tty.usbserial-BG02SIJE

% screen /dev/tty.usbserial-BG02SIJE 115200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The board itself never appeared as a USB drive, so the BeagleBoard Imaging Utility didn't detect it, and while I could start a screen session, no output from the BeagleBoard appeared. This could be a macOS-specific issue, related to security not allowing such USB devices, so I switched strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Succeeded With Linux
&lt;/h3&gt;

&lt;p&gt;On a Linux machine, everything worked as expected! The USB-to-serial cable was properly detected, something you can easily verify with the &lt;code&gt;dmesg&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dmesg
[4:58 PM][2353475.078097] usb 1-5: new full-speed USB device number 7 using xhci_hcd
[2353475.210940] usb 1-5: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00
[2353475.210946] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[2353475.210948] usb 1-5: Product: FT232R USB UART
[2353475.210950] usb 1-5: Manufacturer: FTDI
[2353475.210951] usb 1-5: SerialNumber: BG02SIJE
[2353475.266287] usbcore: registered new interface driver usbserial_generic
[2353475.266305] usbserial: USB Serial support registered for generic
[2353475.269477] usbcore: registered new interface driver ftdi_sio
[2353475.269497] usbserial: USB Serial support registered for FTDI USB Serial Device
[2353475.269533] ftdi_sio 1-5:1.0: FTDI USB Serial Device converter detected
[2353475.269571] usb 1-5: Detected FT232R
[2353475.270001] usb 1-5: FTDI USB Serial Device converter now attached to ttyUSB0

$ sudo apt install screen
$ sudo screen /dev/ttyUSB0 115200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the serial connection established, check the board output in the &lt;code&gt;screen&lt;/code&gt; session and wait for the message &lt;code&gt;Press a key to enter CLI&lt;/code&gt; to appear. You have one second to react, so be fast! :-)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb785ar3ghbe2tussyqhn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb785ar3ghbe2tussyqhn.png" alt="Boot interrupt in the screen tool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then type in the following two commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt; mmc
&amp;gt;&amp;gt; usbdmsc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the board should appear as a USB drive on your computer and as a device in the Imaging Utility for an OS update. I had to do this twice because Wi-Fi was enabled, which caused an error at the end of the first attempt. After disabling the Wi-Fi settings, the update succeeded, and the board rebooted to Ubuntu 24!&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Java 25
&lt;/h2&gt;

&lt;p&gt;Once Ubuntu 24 was up and running on the BeagleV-Fire, installing Java 25 was straightforward using the standard apt install command. Java 25 is the latest Long-Term Support (LTS) version, meaning it will be maintained for a long time. While Java 26 will be released in March, that's a short-term version with only six months of support. I'm happy to start with Java 25 on this board, though Java 26 should work just as well once it becomes available through apt.&lt;/p&gt;

&lt;p&gt;I also installed &lt;a href="https://sdkman.io/" rel="noopener noreferrer"&gt;SDKMAN&lt;/a&gt; and &lt;a href="https://www.jbang.dev/" rel="noopener noreferrer"&gt;JBang&lt;/a&gt; to test a few of the &lt;a href="https://github.com/Pi4J/pi4j-jbang" rel="noopener noreferrer"&gt;Pi4J JBang&lt;/a&gt; examples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt upgrade
sudo apt install zip
curl -s "https://get.sdkman.io" | bash

# Close the terminal and open a new one
sdk install jbang

# Install OpenJDK 25
sudo apt install openjdk-25-jdk

# Get the Pi4J JBang repository
git clone https://github.com/Pi4J/pi4j-jbang.git
cd pi4j-jbang
cd basic
java HelloWorld.java
jbang HelloJavaFXWorld.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Next: Performance Testing
&lt;/h2&gt;

&lt;p&gt;Now that I have Java 25 running on both ARM and RISC-V boards, the big question remains: how do they compare in terms of performance? That's exactly what I plan to explore throughout 2026. My goal is to create a reusable Java performance test that I can run across all these single-board computers to compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ARM processors (like the BeagleY-AI and Raspberry Pi)&lt;/li&gt;
&lt;li&gt;RISC-V processors (like the BeagleV-Fire and BeagleV Ahead)&lt;/li&gt;
&lt;li&gt;Eventually, x86 processors on single-board computers as well&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will help us understand what's achievable with these affordable single-board computers and which architecture performs best for Java development, and which board is the best choice for a specific use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Getting Java running on RISC-V is a reality! While the process required a few extra steps compared to ARM boards, the BeagleV-Fire is now running Ubuntu 24 with Java 25 and is ready for experimentation.&lt;/p&gt;

&lt;p&gt;If you're interested in following along with my "2026 single-board computer testing plan", or if you have specific tests you'd like me to run, please let me know! Don't forget to subscribe to my &lt;a href="https://www.youtube.com/frankdelporte" rel="noopener noreferrer"&gt;YouTube channel&lt;/a&gt; for future updates.&lt;/p&gt;

</description>
      <category>java</category>
      <category>riscv</category>
      <category>javaonriscv</category>
      <category>beagleboard</category>
    </item>
    <item>
      <title>First Test of Java on BeagleBoards (ARM and RISC-V)</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Tue, 10 Feb 2026 19:31:50 +0000</pubDate>
      <link>https://dev.to/fdelporte/first-test-of-java-on-beagleboards-arm-and-risc-v-5d6l</link>
      <guid>https://dev.to/fdelporte/first-test-of-java-on-beagleboards-arm-and-risc-v-5d6l</guid>
      <description>&lt;p&gt;As part of my 2026 learning goals around Java on RISC-V (see &lt;a href="https://webtechie.be/post/2026-01-07-x86-arm-riscv/" rel="noopener noreferrer"&gt;this post about x86 versus ARM versus RISC-V&lt;/a&gt;), I've asked various suppliers to send me evaluation boards. I already published these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2025-11-25-first-test-lattepanda-iota-with-ubuntu-and-java/" rel="noopener noreferrer"&gt;LattePanda IOTA (x86)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2026-01-12-first-test-orangepi-java/" rel="noopener noreferrer"&gt;OrangePi 5 Ultra (ARM) and OrangePi RV2 (RISC-V)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webtechie.be/post/2026-01-16-first-test-visionfive-java/" rel="noopener noreferrer"&gt;VisionFive 2 Lite (RISC-V)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;In this post: BeagleBoards (ARM and RISC-V)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I got all these boards for free, but what I write here and show in the video is not controlled by StarFive or any other supplier.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/pZ8hMuQbk8Y"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  ARM versus RISC-V?
&lt;/h2&gt;

&lt;p&gt;ARM and RISC-V represent two different approaches to processor design. ARM is the established player we know from, e.g., the Raspberry Pi's. It's mature, and has a huge ecosystem of tools and support built over decades. RISC-V is the open-source alternative, free from licensing restrictions and fully transparent. While ARM still leads in performance and tooling today, RISC-V is catching up fast. The real difference isn't just about speed. It's about openness and flexibility. With RISC-V, you're not locked into a vendor's ecosystem, and you have complete visibility into how your hardware works.&lt;/p&gt;

&lt;h2&gt;
  
  
  BeagleBoards
&lt;/h2&gt;

&lt;p&gt;BeagleBoard has a wide range of single-board-computers in Raspberry Pi-like and Arduino-like formats. Here's how the BeagleBoards I received, compare to the latest Raspberry Pi's:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Board&lt;/th&gt;
&lt;th&gt;SOC&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;CPU&lt;/th&gt;
&lt;th&gt;Cores&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://api.pi4j.com/board-information/MODEL_4_B" rel="noopener noreferrer"&gt;Raspberry Pi 4&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;BCM2711&lt;/td&gt;
&lt;td&gt;ARMv8&lt;/td&gt;
&lt;td&gt;Cortex-A72&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1.8Ghz&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.amazon.com.be/-/en/Raspberry-Pi-Model-4GB-LPDDR4/dp/B09TTNF8BT" rel="noopener noreferrer"&gt;68€ (4GB)&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://api.pi4j.com/board-information/MODEL_5_B" rel="noopener noreferrer"&gt;Raspberry Pi 5&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;BCM2712&lt;/td&gt;
&lt;td&gt;ARMv8&lt;/td&gt;
&lt;td&gt;Cortex-A76&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2.4Ghz&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.amazon.com.be/-/en/Raspberry-4GB-Quad-Core-ARMA76-64-bit/dp/B0CK3L9WD3" rel="noopener noreferrer"&gt;79€ (4GB)&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.beagleboard.org/boards/beagley-ai" rel="noopener noreferrer"&gt;BeagleY-AI&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Texas AM67A&lt;/td&gt;
&lt;td&gt;ARM&lt;/td&gt;
&lt;td&gt;Cortex-A53&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1.4Ghz&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.digikey.com/en/products/detail/beagleboard-by-seeed-studio/102991834/22532596" rel="noopener noreferrer"&gt;73$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.beagleboard.org/boards/beaglev-fire" rel="noopener noreferrer"&gt;BeagleV-Fire&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;RISC-V + FPGA&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;1+4&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.digikey.com/en/products/detail/beagleboard/102110898/21706497" rel="noopener noreferrer"&gt;149$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.beagleboard.org/boards/beaglev-ahead" rel="noopener noreferrer"&gt;BeagleV-Ahead&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Alibaba TH1520&lt;/td&gt;
&lt;td&gt;RISC-V&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2GHz&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.digikey.com/en/products/detail/beagleboard/102991698/20380528" rel="noopener noreferrer"&gt;149$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.beagleboard.org/boards/pocketbeagle-2" rel="noopener noreferrer"&gt;PocketBeagle 2&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;ARM&lt;/td&gt;
&lt;td&gt;Cortex-A53&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1.4Ghz&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.digikey.com/en/products/detail/beagleboard/102110780/25927193" rel="noopener noreferrer"&gt;29$&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Test Boards
&lt;/h3&gt;

&lt;p&gt;I received the following boards.&lt;/p&gt;

&lt;h4&gt;
  
  
  BeagleY-AI
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;BeagleY®-AI is a low-cost, open-source, community-supported development platform for developers and hobbyists in a familiar form-factor compatible with accessories available for other popular single board computers. Users benefit from BeagleBoard.org-provided Debian Linux software images with a built-in development environment and the ability to run artificial intelligence applications on a dedicated 4 TOPS co-processor along with real-time I/O tasks on a dedicated 800MHz microcontroller. BeagleY®-AI is designed to meet the needs of professional developers and classroom-environments alike being affordable and easy-to-use, while being open source hardware such that developers barriers are eliminated to how deep the lessons can go or how far you can take the design in practical applications.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.beagleboard.org/boards/beagley-ai" rel="noopener noreferrer"&gt;Product page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.beagleboard.org/boards/beagley/ai/index.html#beagley-ai-home" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  BeagleV-Fire
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;BeagleV®-Fire is a revolutionary single-board computer (SBC) powered by the Microchip’s PolarFire® MPFS025T 5x core RISC-V System on Chip (SoC) with FPGA fabric. BeagleV®-Fire opens up new horizons for developers, tinkerers, and the open-source community to explore the vast potential of RISC-V architecture and FPGA technology. It has the same P8 &amp;amp; P9 cape header pins as BeagleBone Black allowing you to stack your favorite BeagleBone cape on top to expand it’s capability. Built around the powerful and energy-efficient RISC-V instruction set architecture (ISA) along with its versatile FPGA fabric, BeagleV®-Fire SBC offers unparalleled opportunities for developers, hobbyists, and researchers to explore and experiment with RISC-V technology.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.beagleboard.org/boards/beaglev-fire" rel="noopener noreferrer"&gt;Product page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.beagleboard.org/boards/beaglev/fire/index.html#beaglev-fire-home" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  BeagleV-Ahead
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;BeagleV®-Ahead is an open-source RISC-V single board computer (SBC) with BeagleBone Black cape header pins allowing you to stack your favorite BeagleBone cape on top to expand it’s capability. Featuring a powerful quad-core RISC-V processor, BeagleV®-Ahead is designed as an affordable RISC-V enabled pocket-size computer for anybody who want’s to dive deep into the new RISC-V ISA.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.beagleboard.org/boards/beaglev-ahead" rel="noopener noreferrer"&gt;Product page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.beagleboard.org/boards/beaglev/ahead/index.html#beaglev-ahead-home" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.beagleboard.org/beagleboard/linux" rel="noopener noreferrer"&gt;Linux Kernel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/flashing.md" rel="noopener noreferrer"&gt;Flashing Ubuntu OS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.beagleboard.org/distros/beaglev-ahead-ubuntu-2023-07-05" rel="noopener noreferrer"&gt;BeagleV-Ahead Ubuntu 2023-07-05&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.beagleboard.org/boards/beaglev/ahead/02-quick-start.html" rel="noopener noreferrer"&gt;BeagleV-Ahead Quick Start&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  PocketBeagle 2
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;PocketBeagle 2 is an upgraded version of the popular PocketBeagle, designed as an ultra-compact, low-cost, and powerful single-board computer (SBC). Targeted at developers, students, and hobbyists, PocketBeagle 2 retains the simplicity and flexibility of its predecessor while delivering enhanced performance and expanded features to support modern development needs. PocketBeagle 2 is ideal for creating IoT devices, robotics projects, and educational applications. Its small form factor and low power consumption make it a versatile platform for embedded development, whether prototyping or deploying at scale.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.beagleboard.org/boards/pocketbeagle-2" rel="noopener noreferrer"&gt;Product page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.beagleboard.org/boards/pocketbeagle-2/index.html#pocketbeagle-2-home" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.beagleboard.org/boards/techlab" rel="noopener noreferrer"&gt;PocketBeagle TechLab&lt;/a&gt;: &lt;em&gt;Designed from lessons-learned in teaching hundreds of individuals getting their first introduction to programming, Linux, and ultimately hacking the kernel itself.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fquegwtc6f4cqcg5w1lhj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fquegwtc6f4cqcg5w1lhj.jpg" alt="BeagleBoards used for this post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First Tests
&lt;/h2&gt;

&lt;p&gt;The easiest way to get started with a BeagleBoard and burn the latest OS on an SD card, is the &lt;a href="https://www.beagleboard.org/bb-imager" rel="noopener noreferrer"&gt;BeagleBoard Imaging Utility&lt;/a&gt;, available for Windows, macOS and Linux. This is the first supplier of SBC's that provides such a tool that is comparable to the Raspberry Pi Imager Tool. It's a crucial factor to get started with a new type of SBC, and BeagleBoard has done a great job in making this tool available.&lt;/p&gt;

&lt;h3&gt;
  
  
  BeagleY-AI (ARM Processor)
&lt;/h3&gt;

&lt;p&gt;This board delivered the smoothest experience of all four BeagleBoards. Using BeagleBoard's excellent Imaging Utility, I created an SD card with the latest OS, providing the username and password I want to use via the settings. With the SD card installed, I connected it via micro HDMI and USB, and booted into a desktop environment within minutes. After the standard &lt;code&gt;update&lt;/code&gt; and `upgrade, I installed &lt;a href="https://sdkman.io/" rel="noopener noreferrer"&gt;SDKMAN&lt;/a&gt;, Java (Azul Zulu 25.0.2 with JavaFX support), and &lt;a href="https://www.jbang.dev/" rel="noopener noreferrer"&gt;JBang&lt;/a&gt;. The JavaFX test application from tge &lt;a href="//github.com/Pi4J/pi4j-jbang"&gt;Pi4J JBang repository&lt;/a&gt; ran flawlessly, confirming that both Java and JavaFX work perfectly on this ARM-based board. It's very comparable to the Raspberry Pi 5, even sharing similar connector placement, making it an excellent choice for Java development.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
sudo apt update&lt;br&gt;
sudo apt upgrade&lt;br&gt;
sudo apt install zip&lt;br&gt;
curl -s "&lt;a href="https://get.sdkman.io" rel="noopener noreferrer"&gt;https://get.sdkman.io&lt;/a&gt;" | bash&lt;/p&gt;

&lt;h1&gt;
  
  
  Close the terminal and open a new one
&lt;/h1&gt;

&lt;p&gt;sdk install java 25.0.1-zulu-fx&lt;br&gt;
sdk install jbang&lt;/p&gt;

&lt;h1&gt;
  
  
  Close the terminal and open a new one
&lt;/h1&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/Pi4J/pi4j-jbang.git" rel="noopener noreferrer"&gt;https://github.com/Pi4J/pi4j-jbang.git&lt;/a&gt;&lt;br&gt;
cd pi4j-jbang&lt;br&gt;
cd javafx&lt;br&gt;
jbang HelloJavaFXWorld.java&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  BeagleV-Fire (RISC-V Processor)
&lt;/h3&gt;

&lt;p&gt;This board proved challenging due to my Raspberry Pi habits. I initially created an SD card using the Imaging Utility, not realizing the board already has Ubuntu pre-installed in its eMMC storage. Unfortunately, it's running Ubuntu 23.04, which is no longer maintained, preventing me from updating or installing Java through the package manager. The correct approach requires connecting the board via USB to my computer and flashing the eMMC directly using the Imaging Utility's device mode, but I haven't successfully completed this process yet. While Java RISC-V builds exist and should theoretically work, I need to resolve the OS update issue first before confirming Java compatibility.&lt;/p&gt;

&lt;p&gt;Default username and password are &lt;code&gt;beagle:temppwd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
% ssh beagle@10.120.10.11&lt;br&gt;
Ubuntu 23.04&lt;br&gt;
BeagleBoard.org Ubuntu 23.04 Console Image 2023-10-19&lt;br&gt;
Support: https://bbb.io/debian&lt;br&gt;
default username:password is [beagle:temppwd]&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  BeagleV-Ahead (RISC-V Processor)
&lt;/h3&gt;

&lt;p&gt;This larger RISC-V board presents its own unique challenges. Unlike modern boards, it requires a traditional 5-volt barrel connector instead of USB-C for power. I successfully connected to it via SSH over my network, but discovered it runs a custom Linux distribution specifically built for its processor, one I didn't recognize and couldn't identify as Debian or Ubuntu-based. The apt package manager doesn't function on this distribution, leaving me unable to install Java through standard methods. While Java RISC-V builds should theoretically be compatible, I need to dive deeper into the documentation to understand this custom distribution and determine the proper installation approach.&lt;/p&gt;

&lt;p&gt;Default username is &lt;code&gt;root&lt;/code&gt; without a password.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h1&gt;
  
  
  cat /etc/*-release
&lt;/h1&gt;

&lt;p&gt;commit-id:52fbe8443ea11d7e0abf958a8e2a202d67ef40c1&lt;br&gt;
ID=thead-c910&lt;br&gt;
NAME="THEAD C910 Release Distro"&lt;br&gt;
VERSION="1.1.2"&lt;br&gt;
VERSION_ID=1.1.2&lt;br&gt;
PRETTY_NAME="THEAD C910 Release Distro 1.1.2"&lt;br&gt;
BUILD_ID="20230609164851"&lt;br&gt;
HOME_URL="&lt;a href="https://occ.t-head.cn/" rel="noopener noreferrer"&gt;https://occ.t-head.cn/&lt;/a&gt;"&lt;/p&gt;

&lt;h1&gt;
  
  
  apt search openjdk
&lt;/h1&gt;

&lt;p&gt;Sorting... Done&lt;br&gt;
Full Text Search... Done&lt;/p&gt;

&lt;h1&gt;
  
  
  apt install java
&lt;/h1&gt;

&lt;p&gt;Reading package lists... Done&lt;br&gt;
Building dependency tree... Done&lt;br&gt;
E: Unable to locate package java&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  PocketBeagle 2 2 (ARM Processor)
&lt;/h3&gt;

&lt;p&gt;This tiny ARM-based board uses the Cortex A53 processor (the same as the BeagleY-AI), which means Java should run without issues since ARM Java distributions are readily available. I haven't tested it yet, but I'm confident it will work. The exciting part is the included Tech Lab kit with buttons and RGB LEDs that mount directly on top of the board, making it an ideal platform for coding clubs and educational settings where you want to combine programming with physical computing experiments. This compact form factor paired with interactive hardware makes it a promising board for hands-on Java experimentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;My congratulations to BeagleBoard for their documentation website and Imaging Utility! That really sets them apart from other single-board computer suppliers I tested before. Java on BeagleY-AI runs within minutes of starting my tests, and I'm confident I'll be able to use it for further experiments.&lt;/p&gt;

&lt;p&gt;For the other boards, I'll need some more time to figure out how to proceed. The BeagleV-Fire needs a newer version of Ubuntu, and the Linux version on the BeagleV-Ahead is still a mystery to me...&lt;/p&gt;

&lt;p&gt;As I set my goals for 2026 to learn more about different types of single-board-computers that's a perfect conclusion. It's just the beginning of 2026, so I have still more than 10 months this year to achieve my goal ;-) &lt;/p&gt;

</description>
      <category>java</category>
      <category>openjdk</category>
      <category>beagleboard</category>
      <category>riscv</category>
    </item>
    <item>
      <title>JavaFX In Action #25 with Lidiany Cerqueira about CERCA, a tool to detect hallucinated references in scientific papers</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Thu, 05 Feb 2026 15:34:19 +0000</pubDate>
      <link>https://dev.to/fdelporte/javafx-in-action-25-with-lidiany-cerqueira-about-cerca-a-tool-to-detect-hallucinated-references-ecf</link>
      <guid>https://dev.to/fdelporte/javafx-in-action-25-with-lidiany-cerqueira-about-cerca-a-tool-to-detect-hallucinated-references-ecf</guid>
      <description>&lt;p&gt;Every week I collect a list of posts, social messages, videos, etc. related to JavaFX on the &lt;a href="https://www.jfx-central.com/links" rel="noopener noreferrer"&gt;JFX Central Links Of The Week&lt;/a&gt;. That's how I recently found a &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7417956568593481729/" rel="noopener noreferrer"&gt;message from Lidiany Cerqueira on LinkedIn about CERCA&lt;/a&gt;. It's a tool she created during her Christmas break to detect false/hallucinated references in scientific manuscripts.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/QVN57j1zcik"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  About Lidiany
&lt;/h2&gt;

&lt;p&gt;Lidiany Cerqueira is a Senior Software Engineer and Computer Science researcher, living in Brazil, and working at the intersection of software engineering and human values. With over 15 years of industry experience and a PhD in Computer Science, her research interests include software engineering, human-centered computing, and empirical research.&lt;/p&gt;

&lt;p&gt;She has experience in teaching and outreach, working with students from both traditional computer science programs and non-CS backgrounds, and is a strong advocate for diversity and inclusion in technology, and currently serves as a Community Manager at BRAVAS in Tech.&lt;/p&gt;

&lt;p&gt;She created the CERCA application because she serves as an active reviewer for top-tier software engineering venues and is a member of the program committee for several conferences, contributing to the research community through peer review and service.&lt;/p&gt;

&lt;p&gt;You can find her on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lidianycs.site/" rel="noopener noreferrer"&gt;Personal website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/lidianycs/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lidianycs" rel="noopener noreferrer"&gt;GitHub profile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bsky.app/profile/lidianycs.bsky.social" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bravasintech.com/" rel="noopener noreferrer"&gt;Bravas In Tech&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About CERCA
&lt;/h2&gt;

&lt;p&gt;CERCA is an open-source research tool that supports the verification of bibliographic references in scientific manuscripts. It extracts references from PDF files and checks their existence and consistency against authoritative metadata sources, producing explainable diagnostics, audit logs, and reproducible reports.&lt;/p&gt;

&lt;p&gt;You can find more information about CERCA on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lidianycs/cerca" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sourceforge.net/projects/cerca/" rel="noopener noreferrer"&gt;CERCA downloads on Sourceforge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7417956568593481729/" rel="noopener noreferrer"&gt;Message on LinkedIn by Lidiany&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/lidianycs/how-i-built-a-tool-to-detect-ai-generated-fake-references-2891"&gt;Post on dev.to&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used libraries and APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/xdrop/fuzzywuzzy" rel="noopener noreferrer"&gt;JavaWuzzy: FuzzyWuzzy Java Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CeON/CERMINE" rel="noopener noreferrer"&gt;CERMINE: Content ExtRactor and MINEr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.crossref.org/documentation/retrieve-metadata/rest-api/" rel="noopener noreferrer"&gt;Crossref REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openalex.org/how-to-use-the-api/api-overview" rel="noopener noreferrer"&gt;OpenAlex API Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.zenodo.org/" rel="noopener noreferrer"&gt;Zenodo REST API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hkvo8b3i55tanxmistr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hkvo8b3i55tanxmistr.png" alt="Screenshot of CERCA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Video content
&lt;/h2&gt;

&lt;p&gt;00:00 Who is Lidiany&lt;/p&gt;

&lt;p&gt;01:13 The problem of hallucinated references in academic papers&lt;/p&gt;

&lt;p&gt;03:23 The goal of CERCA and why it's developed with Java(FX)&lt;/p&gt;

&lt;p&gt;05:07 Demo of CERCA&lt;/p&gt;

&lt;p&gt;13:30 Reading reference lists from other file formats&lt;/p&gt;

&lt;p&gt;15:32 Export report to text&lt;/p&gt;

&lt;p&gt;16:34 Database APIs used for checking references&lt;/p&gt;

&lt;p&gt;17:47 Papers must be processed locally as they may not be uploaded to any service&lt;/p&gt;

&lt;p&gt;19:30 Why Java(FX) was the best solution to build CERCA&lt;/p&gt;

&lt;p&gt;21:25 A look into the code and the used libraries&lt;/p&gt;

&lt;p&gt;24:49 Call for contributions&lt;/p&gt;

&lt;p&gt;25:53 About the (Brazilian) Java and other communities&lt;/p&gt;

&lt;h2&gt;
  
  
  More JFX In Action...
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://webtechie.be/tags/jfx-in-action/" rel="noopener noreferrer"&gt;Click here for more posts with JFX In Action videos&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>java</category>
      <category>llm</category>
      <category>tooling</category>
    </item>
    <item>
      <title>OpenJDK January 2026 Critical Patch Update and Patch Set Update Released</title>
      <dc:creator>Frank Delporte</dc:creator>
      <pubDate>Fri, 23 Jan 2026 09:56:51 +0000</pubDate>
      <link>https://dev.to/fdelporte/openjdk-january-2026-critical-patch-update-and-patch-set-update-released-374k</link>
      <guid>https://dev.to/fdelporte/openjdk-january-2026-critical-patch-update-and-patch-set-update-released-374k</guid>
      <description>&lt;p&gt;The January 2026 OpenJDK quarterly updates are now (or will soon be) available from various OpenJDK distributors. This quarterly release brings important security fixes and updates to all currently supported Java versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Quarterly Update Cycle
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Every three months&lt;/strong&gt; (in January, April, July, and October), the OpenJDK project releases &lt;strong&gt;security updates, bug fixes, and improvements&lt;/strong&gt; for &lt;strong&gt;all supported Java versions&lt;/strong&gt;. This predictable schedule helps organizations plan their Java updates and maintain secure, stable production environments.&lt;/p&gt;

&lt;p&gt;These quarterly releases come in two flavors: Critical Patch Updates and Patch Set Updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Critical Patch Updates (CPU)
&lt;/h3&gt;

&lt;p&gt;CPU releases focus exclusively on security. They contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixes for security vulnerabilities&lt;/li&gt;
&lt;li&gt;Critical bug fixes only&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CPUs are based on the previous quarter's PSU release with only security patches applied. This conservative approach makes them ideal for deploying urgent security fixes with minimal risk of introducing new issues. If stability is your top priority and you want to avoid any non-security changes, CPU releases are your go-to option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Patch Set Updates (PSU)
&lt;/h3&gt;

&lt;p&gt;PSU releases provide a more comprehensive update by incorporating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All security fixes from the corresponding CPU&lt;/li&gt;
&lt;li&gt;Additional non-security bug fixes&lt;/li&gt;
&lt;li&gt;Alignment with the associated OpenJDK project quarterly release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PSUs offer the full set of improvements and refinements from the OpenJDK community while still maintaining the stability expected from a minor update.&lt;/p&gt;

&lt;p&gt;In an ideal scenario, you install a CPU as soon as possible after a brief test to secure your environment. After that, you start testing with the PSU release for a longer time. Once all your tests are green, switch your environment to the PSU version. This must be completed before the next quarterly update, so you can easily repeat the cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Difference With the Six-Month Release Cycle
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;six-month release cycle&lt;/strong&gt;, introduced with OpenJDK 9, &lt;strong&gt;brings a new major OpenJDK version&lt;/strong&gt; in March and September. For example, on September 16, 2026, we saw the "birth" of Java 25 (25.0.0).&lt;/p&gt;

&lt;p&gt;Since then, we already had the October CPU/PSU release, which brought the first security and bug fixes to all supported versions, so also bumping Java 25 to 25.0.1.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;quarterly cycle brings updates to existing releases&lt;/strong&gt;. For example, the January CPU/PSU release bumps the PSU versions (from/to):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;25.0.1 -&amp;gt; 25.0.2&lt;/li&gt;
&lt;li&gt;21.0.9 -&amp;gt; 21.0.10&lt;/li&gt;
&lt;li&gt;17.0.17 -&amp;gt; 17.0.18&lt;/li&gt;
&lt;li&gt;11.0.29 -&amp;gt; 11.0.30&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Important message: to keep your systems secure, you need to install a JDK update every 3 months. Check &lt;code&gt;java -version&lt;/code&gt; to understand how many updates you missed. For instance, if you installed the first release of JDK 17 (17.0.0), you have missed 18 updates with security and bug fixes by now!&lt;/p&gt;

&lt;h2&gt;
  
  
  Distributor Availability
&lt;/h2&gt;

&lt;p&gt;The beauty of the OpenJDK ecosystem is that multiple distributors provide builds of these releases. Major OpenJDK distributors, including Azul (Zulu), BellSoft, Oracle, Eclipse (Temurin), and others, typically make updated builds available for all currently supported Java versions within a few hours or days. This typically includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Current LTS (Long-Term Support) versions (11, 17, 21, 25).&lt;/li&gt;
&lt;li&gt;The latest non-LTS release (till six months after its release).&lt;/li&gt;
&lt;li&gt;Extended support versions (depending on your distributor, for instance, Azul for Java 6, 7, and 8)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check with your specific OpenJDK distributor to confirm which versions receive updates and the support timeline for your deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  In this January Release
&lt;/h2&gt;

&lt;p&gt;The January release, as stated by Oracle, &lt;em&gt;contains 11 new security patches for Oracle Java SE.  All of these vulnerabilities may be remotely exploitable without authentication, i.e., may be exploited over a network without requiring user credentials. The highest CVSS v3.1 Base Score of vulnerabilities affecting Oracle Java SE is 7.5&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Number of total bug fixes and improvements included in today’s OpenJDK update release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java 25: 380&lt;/li&gt;
&lt;li&gt;Java 21: 384&lt;/li&gt;
&lt;li&gt;Java 17: 349&lt;/li&gt;
&lt;li&gt;Java 11: 65&lt;/li&gt;
&lt;li&gt;Java 8: 64&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Azul has also posted its release notes, which you can &lt;a href="https://docs.azul.com/core/release-notes" rel="noopener noreferrer"&gt;find here&lt;/a&gt;. One of the highlights: &lt;a href="https://docs.azul.com/core/release-notes#changes-in-coordinated-restore-at-checkpoint-crac" rel="noopener noreferrer"&gt;new features in Azul's integration of Coordinated Restore at Checkpoint (CRaC)&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Image Encryption&lt;/strong&gt;: By default, the CRaC images contain application data, including environment variables and arguments, in plaintext. If this data contains secrets and the images are accessible to untrusted parties, you can encrypt the images to ensure the secrets stay hidden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alternative Images&lt;/strong&gt;: Automatically select the best CRaC image at restore. This brings a solution to modern cloud environments where a single checkpoint image may not be enough&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Review the release notes from your OpenJDK distributor to understand the specific fixes and improvements in this quarter's release. Plan your testing and deployment schedule to ensure your Java applications benefit from the latest security patches and bug fixes.&lt;/p&gt;

&lt;p&gt;Mark your calendar, the next quarterly updates and releases arrive on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2026-03-17: OpenJDK 26 release&lt;/li&gt;
&lt;li&gt;2026-04-21: CPU/PSU Update&lt;/li&gt;
&lt;li&gt;2026-07-21: CPU/PSU Update&lt;/li&gt;
&lt;li&gt;2026-09-15: OpenJDK 27 release&lt;/li&gt;
&lt;li&gt;2026-10-20: CPU/PSU Update&lt;/li&gt;
&lt;li&gt;2027-01-19: CPU/PSU Update&lt;/li&gt;
&lt;li&gt;2027-03-23: OpenJDK 28 release&lt;/li&gt;
&lt;li&gt;2027-04-20: CPU/PSU Update&lt;/li&gt;
&lt;li&gt;2027-07-20: CPU/PSU Update&lt;/li&gt;
&lt;li&gt;2027-09-21: OpenJDK 29 (LTS) release&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>openjdk</category>
      <category>cve</category>
    </item>
  </channel>
</rss>
