Skip to content

Fix windows-arm64 launcher: unsupported platform, classpath crash, WebView crash - #727

Merged
Cervator merged 4 commits into
masterfrom
fix/windows-arm64-launcher-startup
Aug 15, 2026
Merged

Cervator merged 4 commits into
masterfrom
fix/windows-arm64-launcher-startup

Conversation

@soloturn

@soloturn soloturn commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What's broken

The nightly windows-arm64 distribution currently can't start at all, for three independent reasons hit one after another:

  1. Platform.fromOsAndArch() has no case for Windows+ARM64. Arch.ARM64 already exists and jre.gradle.kts already builds a dedicated WindowsArm64 JRE distribution, but the platform check throws Unsupported platform: OS 'WINDOWS', arch 'ARM64' before the launcher configuration is even created.

  2. The generated bin\TerasologyLauncher.bat crashes with The input line is too long. Gradle's default Windows start-script template lists every dependency jar individually with its full absolute path substituted in. With ~150 jars that easily exceeds cmd.exe's 8191-character line limit once installed. This mainly bites windows-arm64 specifically: unlike Windows64, it has no launch4j .exe wrapper (jre.gradle.kts only wires createExe/createTerasologyExe in for os == "Windows64"), so it's the only Windows target that ships and depends on this generated .bat. The .exe wrapper already avoids this with classpath.set(listOf("lib/*")) in build.gradle.kts.

  3. Constructing a WebView (Changelog and About tabs) throws UnsatisfiedLinkError. OpenJFX has never shipped a working WebKit native library for Windows/aarch64 - see JDK-8314064 / openjdk/jfx#439, whose own description says it's "cross compiling JavaFX base modules (excluding media and webkit) for Windows AArch64." The media follow-up was attempted separately and abandoned after runtime crashes; no webkit port exists at all. Note that javafx.application.Platform.isSupported(ConditionalFeature.WEB) is not a reliable guard here - verified empirically, it returns true on a real Windows/aarch64 machine (BellSoft's vendor JRE still bundles a javafx.web module for API compatibility) and then crashes anyway.

What this PR does

  • platform: recognize Windows on ARM64 - adds WINDOWS_ARM64 to the Platform enum, plus Platform#supportsWebView() used by the third commit.
  • build: use a wildcard classpath in the Windows start script - switches buildres/scripts/windowsStartScript.txt from Gradle's per-jar $classpath to %APP_HOME%/lib/*, matching what the launch4j .exe already does.
  • ui: fall back to plain text where WebView isn't available - ChangelogViewController and AboutViewController now check Platform#supportsWebView() before constructing a WebView, falling back to a plain TextArea (HTML docs have their tags stripped via Jsoup) instead of crashing the whole launcher.

Testing

Verified end-to-end on a real Windows 11 ARM64 machine using the official nightly windows-arm64 distribution (4.9.0-dev.19+2da4e3f): patched TerasologyLauncher.jar in place with these changes (compiled against Java 17 target, i.e. bytecode-compatible with the bundled BellSoft JRE) and confirmed the launcher starts and its main window comes up, where it previously failed at three successive points as described above.

🤖 Generated with Claude Code

soloturn and others added 3 commits August 9, 2026 18:11
Platform.fromOsAndArch() had no case for OS.WINDOWS + Arch.ARM64, even
though Arch.ARM64 already existed and jre.gradle.kts already builds a
dedicated "WindowsArm64" JRE distribution. Every launch on that
distribution hit:

    Unsupported platform: OS 'WINDOWS', arch 'ARM64'

and failed before the launcher configuration was even created.

Also adds Platform#supportsWebView(), used by a follow-up commit: it
identifies the one platform where OpenJFX's javafx.web module is
present but not functional.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CreateStartScripts's default Windows template lists every dependency
jar individually with its full absolute path substituted in for
APP_HOME. With ~150 jars this comfortably exceeds cmd.exe's
8191-character line length limit once installed, and the script fails
immediately with:

    The input line is too long.
    The syntax of the command is incorrect.

This mainly affects the "windows-arm64" distribution: unlike
Windows64, it has no launch4j .exe wrapper (jre.gradle.kts only wires
createExe/createTerasologyExe in for os == "Windows64"), so it's the
only Windows target that actually ships and depends on this generated
.bat. The .exe wrapper already sidesteps this with a plain
`classpath.set(listOf("lib/*"))` in build.gradle.kts - apply the same
wildcard here instead of Gradle's per-jar $classpath.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both the Changelog and About tabs eagerly construct a WebView on
launcher startup. OpenJFX has never shipped a WebKit native library
for Windows/aarch64 (see https://bugs.openjdk.org/browse/JDK-8314064,
whose PR explicitly excludes javafx.web and javafx.media - the
follow-up media port was attempted separately and abandoned after
crashing, and no equivalent webkit port exists at all), so on that
platform merely instantiating a WebView throws UnsatisfiedLinkError
from WebEngine's static initializer, and the whole launcher fails to
start.

javafx.application.Platform.isSupported(ConditionalFeature.WEB) is
*not* a reliable guard for this: it only reports whether the
javafx.web module was compiled in, not whether its native library
actually works on the current OS/arch. Verified empirically - on a
real Windows/aarch64 machine with BellSoft's JRE it returns true and
then crashes anyway, because that vendor JRE still bundles a
javafx.web module (for API compatibility, presumably reusing the
Linux-classified artifact) with no working backend behind it.

Use the new Platform#supportsWebView() instead, which is exact about
the one platform this currently affects. Where WebView isn't
supported: the Changelog tab shows raw Markdown text, and the About
tab strips HTML tags via Jsoup before displaying plain text - both
readable, neither a rendering match for the WebView-based HTML view,
but the launcher starts instead of crashing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d657fe0c-afde-42df-a31d-371eb407e106

📥 Commits

Reviewing files that changed from the base of the PR and between 9e2e3cd and 0577884.

📒 Files selected for processing (4)
  • build.gradle.kts
  • src/main/java/org/terasology/launcher/platform/Platform.java
  • src/main/java/org/terasology/launcher/ui/AboutViewController.java
  • src/main/java/org/terasology/launcher/ui/ChangelogViewController.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/org/terasology/launcher/ui/ChangelogViewController.java
  • src/main/java/org/terasology/launcher/ui/AboutViewController.java

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for running the launcher on Windows ARM64 devices.
    • Added automatic text-based fallback when WebView rendering is unavailable.
    • Improved changelog and About page display across supported and unsupported platforms.
  • Bug Fixes

    • Windows startup now reliably loads bundled libraries without command-line length issues.
    • Improved content layout and anchoring across different screen sizes.

Walkthrough

The launcher adds Windows ARM64 detection and avoids the Windows command-line classpath limit. About and changelog views now detect WebView support and use read-only text fallbacks when WebKit is unavailable.

Changes

Windows ARM64 and launcher support

Layer / File(s) Summary
Platform detection and Windows launcher
buildres/scripts/windowsStartScript.txt, src/main/java/org/terasology/launcher/platform/Platform.java
The launcher maps Windows ARM64 to a dedicated platform value. supportsWebView() reports WebView as unsupported on Windows ARM64. The Windows script uses the bundled lib/* classpath.
About view rendering fallback
build.gradle.kts, src/main/java/org/terasology/launcher/ui/AboutViewController.java
About content uses WebView when supported. Otherwise, Jsoup converts HTML to text, and other files are displayed in a wrapped, non-editable TextArea.
Changelog view rendering fallback
src/main/java/org/terasology/launcher/ui/ChangelogViewController.java, src/main/resources/org/terasology/launcher/views/changelog-view.fxml
The changelog pane creates either a configured WebView or a read-only text view. FXML now provides the container for either rendering path.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 05778

The PR changes Windows ARM64 platform detection, launcher classpath handling, and WebView fallback behavior; no actionable merge-blocking risk remains in the supplied evidence.

Sequence Diagram(s)

sequenceDiagram
  participant Launcher
  participant Platform
  participant AboutViewController
  participant ChangelogViewController
  participant WebView
  participant TextArea
  Launcher->>Platform: resolve operating system and architecture
  Platform-->>AboutViewController: report WebView capability
  Platform-->>ChangelogViewController: report WebView capability
  alt WebView supported
    AboutViewController->>WebView: render About content
    ChangelogViewController->>WebView: render changelog HTML
  else WebView unsupported
    AboutViewController->>TextArea: display text fallback
    ChangelogViewController->>TextArea: display raw changes
  end
Loading

Possibly related PRs

  • MovingBlocks/TerasologyLauncher#719: Both PRs modify Windows launcher classpath handling. This PR switches the startup script to lib/*, while the related PR configures Launch4j with the same wildcard classpath.

Poem

A rabbit hops where WebKit ends,
And finds a text view among friends.
ARM64 joins the platform line,
While lib/* keeps launchers fine.
HTML turns to words with cheer.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the three main Windows ARM64 launcher fixes: platform support, classpath handling, and WebView failures.
Description check ✅ Passed The description directly explains the three startup failures, the implemented fixes, and the end-to-end Windows ARM64 verification.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/windows-arm64-launcher-startup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Two follow-ups from review of the windows-arm64 fixes; no behaviour change intended on any platform.

`AboutViewController` now uses jsoup directly, but jsoup was only on the classpath transitively, via `flexmark-all`'s html2md converter. That compiles today and would keep compiling right up until flexmark is bumped or narrowed to the modules actually used — at which point the break surfaces as an error in the About tab rather than as a missing dependency. Declared at 1.15.4, the version flexmark already resolves, so the dependency graph is unchanged.

The WebView-support check was copied into both view controllers, each with its own comment and its own evaluation timing (`static final` in one, per-`initialize()` in the other). Since it answers a question about the platform, not about either view, it moves to `Platform.currentSupportsWebView()` — one home for the fallback policy, and one place to extend when the next platform needs it.

Left alone deliberately: `javafx.scene.Node` stays fully qualified in both controllers, because both already import flexmark's `Node`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@agent-refr

Copy link
Copy Markdown

Nice work — went through this and all three fixes hold up. A few things I verified against the codebase, in case it's useful for the record:

  • Adding WINDOWS_ARM64 is safe: nothing switches exhaustively over Platform, and the consumers (LauncherDirectoryUtils, GameStarter) branch on isWindows()/isMac()/isLinux(), which the new constant satisfies. Platform isn't used for game-artifact selection either, so this can't make the launcher request a windows-arm64 game build that doesn't exist. Arch detection already mapped aarch64, so the missing fromOsAndArch branch really was the whole gap.
  • The classpath wildcard follows existing precedent rather than inventing one — launch4j already uses classpath.set(listOf("lib/*")) for both exes, and %APP_HOME%/lib/* matches the forward-slash style already used on the %APP_HOME%/jre/ line in the same template. jre.gradle.kts does gate the exes behind if (os == "Windows64"), so WindowsArm64 is genuinely .bat-only.
  • Dropping the WebView from changelog-view.fxml is fine even though application.fxml also uses fx:id="changelogView" — those live in separate FXML namespaces.

I'm pushing a small follow-up commit for two things:

  1. jsoup is now used directly but was only on the classpath transitively, via flexmark-all → flexmark-html2md-converter → jsoup 1.15.4. Declared explicitly at that same version so the resolved graph is unchanged. Worth doing because flexmark is already pinned deliberately here, so a future bump or a narrowing to the modules actually used would break the About tab rather than report a missing dependency.
  2. The WebView-support check was copied into both controllers with different comments and different evaluation timing (static final in one, per-initialize() in the other). Folded into Platform.currentSupportsWebView() so the fallback policy has one home.

Two I left alone rather than changing:

  • The added setLeftAnchor/setRightAnchor in AboutViewController.createPaneFor affect the WebView path on every platform, not just the fallback. Likely an improvement, but it's a cross-platform layout change riding along in an arm64 fix — worth at least a line in the PR description.
  • In the fallback, markdown renders as raw source (# headers, []() links) while HTML gets tag-stripped via jsoup. Reasonable for a fallback; flexmark is right there if you want to give markdown the same treatment later.

Also worth noting the fully-qualified javafx.scene.Node reads odd at first glance but is necessary — both controllers already import flexmark's Node.

One caveat: I don't have a Windows ARM64 machine, so the runtime symptoms (the 8191-character command-line overflow and the WebView UnsatisfiedLinkError) I took on trust rather than reproducing. The reasoning and JDK-8314064 line up.

@Cervator Cervator left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had agent check locally and looked over a few things. Ran the launcher from source on my M1 Mac and it ran fine, then downloaded a game release which promptly failed due to natives - but that's the old stable release and as such probably not unexpected 👍

@Cervator
Cervator merged commit f951a31 into master Aug 15, 2026
4 checks passed
@Cervator
Cervator deleted the fix/windows-arm64-launcher-startup branch August 15, 2026 02:44
soloturn added a commit that referenced this pull request Aug 23, 2026
…bView crash (#727)

* platform: recognize Windows on ARM64

Platform.fromOsAndArch() had no case for OS.WINDOWS + Arch.ARM64, even
though Arch.ARM64 already existed and jre.gradle.kts already builds a
dedicated "WindowsArm64" JRE distribution. Every launch on that
distribution hit:

    Unsupported platform: OS 'WINDOWS', arch 'ARM64'

and failed before the launcher configuration was even created.

Also adds Platform#supportsWebView(), used by a follow-up commit: it
identifies the one platform where OpenJFX's javafx.web module is
present but not functional.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* build: use a wildcard classpath in the Windows start script

CreateStartScripts's default Windows template lists every dependency
jar individually with its full absolute path substituted in for
APP_HOME. With ~150 jars this comfortably exceeds cmd.exe's
8191-character line length limit once installed, and the script fails
immediately with:

    The input line is too long.
    The syntax of the command is incorrect.

This mainly affects the "windows-arm64" distribution: unlike
Windows64, it has no launch4j .exe wrapper (jre.gradle.kts only wires
createExe/createTerasologyExe in for os == "Windows64"), so it's the
only Windows target that actually ships and depends on this generated
.bat. The .exe wrapper already sidesteps this with a plain
`classpath.set(listOf("lib/*"))` in build.gradle.kts - apply the same
wildcard here instead of Gradle's per-jar $classpath.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* ui: fall back to plain text where WebView isn't available

Both the Changelog and About tabs eagerly construct a WebView on
launcher startup. OpenJFX has never shipped a WebKit native library
for Windows/aarch64 (see https://bugs.openjdk.org/browse/JDK-8314064,
whose PR explicitly excludes javafx.web and javafx.media - the
follow-up media port was attempted separately and abandoned after
crashing, and no equivalent webkit port exists at all), so on that
platform merely instantiating a WebView throws UnsatisfiedLinkError
from WebEngine's static initializer, and the whole launcher fails to
start.

javafx.application.Platform.isSupported(ConditionalFeature.WEB) is
*not* a reliable guard for this: it only reports whether the
javafx.web module was compiled in, not whether its native library
actually works on the current OS/arch. Verified empirically - on a
real Windows/aarch64 machine with BellSoft's JRE it returns true and
then crashes anyway, because that vendor JRE still bundles a
javafx.web module (for API compatibility, presumably reusing the
Linux-classified artifact) with no working backend behind it.

Use the new Platform#supportsWebView() instead, which is exact about
the one platform this currently affects. Where WebView isn't
supported: the Changelog tab shows raw Markdown text, and the About
tab strips HTML tags via Jsoup before displaying plain text - both
readable, neither a rendering match for the WebView-based HTML view,
but the launcher starts instead of crashing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* refactor: declare jsoup explicitly and share the WebView-support check

Two follow-ups from review of the windows-arm64 fixes; no behaviour change intended on any platform.

`AboutViewController` now uses jsoup directly, but jsoup was only on the classpath transitively, via `flexmark-all`'s html2md converter. That compiles today and would keep compiling right up until flexmark is bumped or narrowed to the modules actually used — at which point the break surfaces as an error in the About tab rather than as a missing dependency. Declared at 1.15.4, the version flexmark already resolves, so the dependency graph is unchanged.

The WebView-support check was copied into both view controllers, each with its own comment and its own evaluation timing (`static final` in one, per-`initialize()` in the other). Since it answers a question about the platform, not about either view, it moves to `Platform.currentSupportsWebView()` — one home for the fallback policy, and one place to extend when the next platform needs it.

Left alone deliberately: `javafx.scene.Node` stays fully qualified in both controllers, because both already import flexmark's `Node`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Rasmus Praestholm <cervator@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants