From 25a17cd0bc93e9bb8f4e9468f03c2e1050984318 Mon Sep 17 00:00:00 2001 From: floriankirmaier Date: Sun, 14 Jun 2026 22:07:12 +0200 Subject: [PATCH 1/2] Run jpro-platform on JavaFX 25.0.2 + jfx-25-sandec; add failing routing TextFlow leak test The TextFlow-removed-children leak reproduces on JavaFX 25 headless rendering. Co-Authored-By: Claude Opus 4.8 (1M context) --- gradle.properties | 4 ++-- .../routing/crawl/TestMemoryTester.scala | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 1243ed23..3e51dd87 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ JPRO_VERSION = 2026.2.0 -JAVAFX_BUILD_VERSION = 17.0.18 +JAVAFX_BUILD_VERSION = 25.0.2 JAVAFX_EXAMPLES_VERSION = 23.0.2 JAVAFX_25_VERSION = 25.0.2 SIMPLEFX_VERSION = 3.3.3 @@ -34,7 +34,7 @@ ASSERTJ_VERSION = 3.27.7 HAMCREST_VERSION = 3.0 MOCKITO_VERSION = 5.21.0 TESTFX_VERSION = 4.0.18-jpms -MONOCLE_VERSION = jfx-21-sandec +MONOCLE_VERSION = jfx-25-sandec SLF4J_API_VERSION = 2.0.17 LOGBACK_VERSION = 1.5.32 diff --git a/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala b/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala index d15c3a2c..5c964a39 100644 --- a/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala +++ b/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala @@ -51,6 +51,25 @@ class TestMemoryTester { } + // Mirrors jpro-website CheckForLeaks.routeWithLeaf: same shape, only the "/x" leaf differs. + private def routeWithLeaf(leaf: () => javafx.scene.Node): () => Route = () => + Route.empty() + .and(Route.get("/", r => { + val link = new javafx.scene.control.Label("to x") + one.jpro.platform.routing.LinkUtil.setLink(link, "/x", "desc") + Response.node(new javafx.scene.layout.VBox(link)) + })) + .and(Route.get("/x", r => Response.node(leaf()))) + + private def crawlAndCheck(route: () => Route): Unit = { + val result = AppCrawler.crawlRoute("http://localhost", () => route()) + MemoryTester.testForLeaks(result, () => route()) + } + + @Test + def textFlowLeakTest(): Unit = + crawlAndCheck(routeWithLeaf(() => new javafx.scene.text.TextFlow(new javafx.scene.text.Text("hello world")))) + @Test def simpleFailingTest3(): Unit = { From 1688ce5a6e531404076d695943911e5180a245f8 Mon Sep 17 00:00:00 2001 From: floriankirmaier Date: Sun, 14 Jun 2026 22:07:27 +0200 Subject: [PATCH 2/2] Fix routing removed-children leak: swap page content while container is hidden Setting the container not-tree-visible during the swap makes Parent skip peer.addToRemoved, so the removed page is not retained by the NG peer. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../routing/sessionmanager/SessionManagerDesktop.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala b/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala index c4795ce9..7ee3ea67 100644 --- a/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala +++ b/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala @@ -39,7 +39,12 @@ class SessionManagerDesktop(val webApp: RouteNode) extends SessionManager { THIS page.url = url isFullscreen = page.fullscreen + // JFX removed-children retention workaround: swap while the container is not tree-visible + // so Parent skips adding the old page to the NG peer's removed-list (which a broken/absent + // render pulse would otherwise never clear). + container.setVisible(false) container.children = List(page.realContent) + container.setVisible(true) scrollpane.vvalue = 0.0 if(oldView != null && oldView != page) { oldView.onClose()