Problem
A Minecraft server needs a specific Java major (1.16 → Java 8, 1.18 → 17, 1.20.5+/1.21 → 21). That Java may not be installed at all, or the machine may only have the wrong one. Today the launcher falls back to whatever java is on PATH (detectJava('') in src/main/core/java.ts), which ignores both the scan list and the version requirement — so the user gets a cryptic crash instead of a fix.
What the user asked for
When setting up a server, the required Java can differ between versions and may not be installed. If a suitable Java can't be auto-selected from the installed ones — or none exists — warn and ask whether to install it, then install into the app's own working directory. Java paths must be configurable per server.
Design
Two independently-revertible vertical slices:
- Slice 1 — detect & auto-pick (no network). Pure selection logic that, given the requirement (
shared/javaCompat.ts) and the installed JREs (core/javaScan.ts), picks a compatible install (respecting maxKnownGood, so a 1.12 server never gets Java 21). A one-click "Use Java N" quick-fix in the args editor writes the chosen executable into the per-server javaPath — never left as ''/auto, which is the bug we're fixing.
- Slice 2 — install if missing (network). Download a Temurin JRE from Adoptium into
<baseDir>/java/temurin-<major>/ (which javaScan already scans), verify its SHA256, extract via the existing zip-slip-safe path, then pin it per-server. Always opt-in via an "Install Java N" button — never automatic.
Decisions
- Vendor: Eclipse Temurin (Adoptium) — redistributable, no login, clean API. JRE (not JDK): enough to run a server, smaller. Forge/NeoForge
--installServer may want a full JDK — out of scope, noted.
- Location:
<baseDir>/java/ so a provisioned runtime auto-appears in the existing picker; keeps the portable app self-contained.
- Per-server: reuses the existing
ServerConfig.java.javaPath; the fix is to write it, not add a field.
Sub-issues
Problem
A Minecraft server needs a specific Java major (1.16 → Java 8, 1.18 → 17, 1.20.5+/1.21 → 21). That Java may not be installed at all, or the machine may only have the wrong one. Today the launcher falls back to whatever
javais onPATH(detectJava('')insrc/main/core/java.ts), which ignores both the scan list and the version requirement — so the user gets a cryptic crash instead of a fix.What the user asked for
Design
Two independently-revertible vertical slices:
shared/javaCompat.ts) and the installed JREs (core/javaScan.ts), picks a compatible install (respectingmaxKnownGood, so a 1.12 server never gets Java 21). A one-click "Use Java N" quick-fix in the args editor writes the chosen executable into the per-serverjavaPath— never left as''/auto, which is the bug we're fixing.<baseDir>/java/temurin-<major>/(whichjavaScanalready scans), verify its SHA256, extract via the existing zip-slip-safe path, then pin it per-server. Always opt-in via an "Install Java N" button — never automatic.Decisions
--installServermay want a full JDK — out of scope, noted.<baseDir>/java/so a provisioned runtime auto-appears in the existing picker; keeps the portable app self-contained.ServerConfig.java.javaPath; the fix is to write it, not add a field.Sub-issues
pickJavaFor/provisionPlan)