Add a build script that picks a JDK Gradle can run on

A plain ./gradlew build fails outright on a machine whose default java
is newer than 23, which is now an ordinary thing for a distro to ship.
Gradle 8.12 cannot run there, and what it says about it is that it
could not create task ':test' because type T is not present - nothing
about Java, and nothing to act on.

build.sh picks a JDK between 17 and 23 and builds with that. JAVA_HOME
wins if it already points at a usable one, otherwise the openjdk paths
are tried in turn; if there is nothing to pick it says so and names the
range, rather than leaving the Gradle error to be decoded. Arguments
pass through, so it is a wrapper around the wrapper and not a second
way to describe the build.

It reports the jar by reading mod_id and mod_version out of
gradle.properties instead of listing build/libs, which keeps old
versions sitting in that directory from being mistaken for the build
that just ran.

The toolchain is untouched by any of this - the mod still compiles
against Java 21, whatever Gradle itself is running on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gem-slots-and-the-fangs-element
Amir Alexander Abdelbaki 2026-08-14 14:50:45 +02:00
parent cd8993ea25
commit 5411797799
2 changed files with 72 additions and 3 deletions

View File

@ -238,11 +238,24 @@ new piece is wanted rather than a repaint of an existing one.
## Building ## Building
```sh ```sh
./gradlew build ./build.sh
``` ```
Needs nothing but NeoForge - Truly Modular is a runtime dependency only, since The jar lands in `build/libs/`. Needs nothing but NeoForge - Truly Modular is a
this mod talks to it purely through datapack JSON. runtime dependency only, since this mod talks to it purely through datapack
JSON.
`./gradlew build` does the same thing, and is fine if the java on your path is
one Gradle can run on. Gradle 8.12 cannot run on a JDK newer than 23, which a
distro's default java may well be by now, and the failure when it is says
`Could not create task ':test'` and `Type T not present` without ever mentioning
Java. `build.sh` exists to pick a JDK between 17 and 23 - honouring `JAVA_HOME`
if it already points at one - and to say what is wrong in as many words when
there is none to pick. Extra arguments are passed straight through, so
`./build.sh clean build` and `./build.sh --info` work.
None of this touches what the mod is compiled against: the toolchain in
`build.gradle` is Java 21 either way, and Gradle provisions it if it is missing.
## Regenerating materials ## Regenerating materials

56
build.sh Executable file
View File

@ -0,0 +1,56 @@
#!/usr/bin/env bash
# Builds the mod jar into build/libs/.
#
# Gradle 8.12 cannot run on a JDK newer than 23, and a distro's default java is
# often newer than that, so this picks a JDK Gradle can run on rather than
# leaving you to read the "Type T not present" failure that comes of not doing
# so. The build itself still compiles against Java 21 either way - that is the
# toolchain in build.gradle, and Gradle provisions it if it is missing.
set -euo pipefail
cd "$(dirname "$0")"
# Major version of the java at $1/bin/java, or nothing if it will not run.
java_major() {
local out
out=$("$1/bin/java" -version 2>&1) || return 0
sed -n 's/^[^"]*"\([0-9]*\).*/\1/p' <<<"$out" | head -1
}
usable() {
local major
[ -x "$1/bin/java" ] || return 1
major=$(java_major "$1")
[ -n "$major" ] && [ "$major" -ge 17 ] && [ "$major" -le 23 ]
}
if [ -z "${JAVA_HOME:-}" ] || ! usable "$JAVA_HOME"; then
for candidate in /usr/lib/jvm/java-{21,17}-openjdk /usr/lib/jvm/java-{21,17}-openjdk-amd64; do
if usable "$candidate"; then
export JAVA_HOME="$candidate"
break
fi
done
fi
if [ -z "${JAVA_HOME:-}" ] || ! usable "$JAVA_HOME"; then
echo "build.sh: no JDK between 17 and 23 found - Gradle 8.12 cannot run on anything newer." >&2
echo "Install one (e.g. pacman -S jdk17-openjdk) or point JAVA_HOME at it." >&2
exit 1
fi
echo "build.sh: using JDK $(java_major "$JAVA_HOME") at $JAVA_HOME"
./gradlew build "$@"
# Name the jar this run produced. Old versions linger in build/libs/, so listing
# the whole directory would be ambiguous about which one is current.
prop() { sed -n "s/^$1=//p" gradle.properties; }
jar="build/libs/$(prop mod_id)-$(prop mod_version).jar"
echo
if [ -f "$jar" ]; then
echo "Built: $jar"
else
echo "build.sh: expected $jar, but it is not there." >&2
exit 1
fi