Require Java 21 exactly and pin the unit to it

NeoForge 21.1.x targets Java 21. Fedora 43 ships an early-access JDK 26 as the
default java, which satisfied the ">= 21" check and then failed inside
ModLauncher — the server started, logged "JVM identified as ... 26-ea+32", and
died with no obvious cause.

mc-service-setup.sh now locates a real Java 21 under /usr/lib/jvm, refuses to
continue if there is none, and writes its absolute path into ExecStart so the
service does not follow whatever /usr/bin/java points at later.

install.sh checks for Java 21 specifically rather than for any java, so the
prerequisite step actually installs it on a host that already has a newer JDK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
main
Amir Alexander Abdelbaki 2026-08-06 00:55:14 +02:00
parent c4074e8dbc
commit f1731698ed
2 changed files with 43 additions and 7 deletions

View File

@ -63,7 +63,6 @@ step "Checking prerequisites"
MISSING=()
need() { command -v "$1" >/dev/null || MISSING+=("$2"); }
need java java-21-openjdk-headless
need curl curl
need go golang
need python3 python3
@ -71,6 +70,11 @@ need zfs zfs
need findmnt util-linux
need mkfifo coreutils
# Any java is not enough: NeoForge 21.1.x needs 21 exactly.
if ! ls /usr/lib/jvm/java-21-openjdk*/bin/java >/dev/null 2>&1; then
MISSING+=(java-21-openjdk-headless)
fi
if [ "${#MISSING[@]}" -gt 0 ]; then
info "missing: ${MISSING[*]}"
if (( CHECK_ONLY )); then
@ -84,8 +88,12 @@ else
info "all present"
fi
jver="$(java -version 2>&1 | head -1 | grep -oE '"[0-9]+' | tr -d '"' || echo 0)"
[ "${jver:-0}" -ge 21 ] || warn "java is $jver; NeoForge for 1.21.x wants 21"
if ls /usr/lib/jvm/java-21-openjdk*/bin/java >/dev/null 2>&1; then
info "java 21 present: $(ls -d /usr/lib/jvm/java-21-openjdk*/bin/java | head -1)"
else
die "Java 21 is still missing after the install step.
sudo dnf install java-21-openjdk-headless"
fi
if ! mountpoint -q "$SHARE"; then
die "$SHARE is not a mountpoint — the ZFS dataset is not mounted.

View File

@ -102,10 +102,38 @@ mountpoint -q "$SHARE" || die "$SHARE is not a mountpoint — the ZFS dataset is
Check 'zpool status' and 'zfs mount -a' first; installing a server onto the
unmounted path would fill the root filesystem instead of the pool."
command -v java >/dev/null || die "java not found — install it first: dnf install java-21-openjdk-headless"
# NeoForge 21.1.x targets Java 21 exactly. A newer JDK on PATH — Fedora ships
# early-access builds — passes a ">= 21" test and then fails inside ModLauncher,
# so find a real 21 and pin the unit to its absolute path.
java_version_of() { "$1" -version 2>&1 | head -1 | grep -oE '"[0-9]+' | tr -d '"'; }
jver="$(java -version 2>&1 | head -1 | grep -oE '"[0-9]+' | tr -d '"' || echo 0)"
[ "${jver:-0}" -ge 21 ] || warn "java looks like version $jver; NeoForge for 1.21.x needs 21"
find_java21() {
local c
for c in /usr/lib/jvm/java-21-openjdk*/bin/java \
/usr/lib/jvm/java-21*/bin/java \
/usr/lib/jvm/*-21-*/bin/java \
/usr/lib/jvm/*21*/bin/java; do
[ -x "$c" ] || continue
[ "$(java_version_of "$c")" = "21" ] && { printf '%s' "$c"; return 0; }
done
if command -v java >/dev/null && [ "$(java_version_of "$(command -v java)")" = "21" ]; then
command -v java
return 0
fi
return 1
}
JAVA_BIN="$(find_java21 || true)"
if [ -z "$JAVA_BIN" ]; then
have="none"
command -v java >/dev/null && have="$(java_version_of "$(command -v java)")"
die "no Java 21 found (default java is version $have).
NeoForge for Minecraft 1.21.x needs Java 21 specifically — a newer JDK
fails inside ModLauncher rather than refusing to start.
sudo dnf install java-21-openjdk-headless
then re-run."
fi
info "java 21: $JAVA_BIN"
# ------------------------------------------------------------------ user ----
@ -355,7 +383,7 @@ StandardError=journal
RuntimeDirectory=minecraft
RuntimeDirectoryMode=0755
ExecStartPre=/bin/sh -c 'rm -f $FIFO && mkfifo -m 0660 $FIFO'
ExecStart=/bin/bash -c 'exec 3<>$FIFO; exec /usr/bin/java @$SHARE/user_jvm_args.txt @$ARGS_FILE nogui <&3'
ExecStart=/bin/bash -c 'exec 3<>$FIFO; exec $JAVA_BIN @$SHARE/user_jvm_args.txt @$ARGS_FILE nogui <&3'
ExecStop=/bin/sh -c '/bin/echo stop > $FIFO'
# Generous: a big world with many chunks loaded can take a while to save.