#!/usr/bin/env bash # JEP 513 (Flexible Constructor Bodies): final in JDK 25, no --enable-preview. # Regenerates every file in output/. JDK25=/path JDK27=/path [JDK21=/path] ./run.sh set -uo pipefail unset JAVA_TOOL_OPTIONS HERE="$(cd "$(dirname "$0")" && pwd)" JDK25="${JDK25:-/opt/jdks/jdk-25.0.4.1+1}"; JDK27="${JDK27:-/opt/jdks/jdk27}"; JDK21="${JDK21:-}" OUT="$HERE/output"; mkdir -p "$OUT"; B="$(mktemp -d)"; trap 'rm -rf "$B"' EXIT cd "$HERE" v() { "$1/bin/java" -version 2>&1 | sed -n 2p; } # compile SRC with JDK, then run CLASS from it; prints a header naming the JDK cr() { local jdk="$1" src="$2" cls="$3"; local o="$B/$(basename "$jdk")-$cls"; mkdir -p "$o" echo "\$ javac $src && java $cls ($(v "$jdk"))" "$jdk/bin/javac" -d "$o" "$src" 2>&1 && "$jdk/bin/java" -cp "$o" "$cls" 2>&1; } { cr "$JDK25" src/ValidateBeforeSuper.java ValidateBeforeSuper; echo; cr "$JDK27" src/ValidateBeforeSuper.java ValidateBeforeSuper } > "$OUT/01-validate-before-super.txt" { cr "$JDK25" src/BeforeJava25.java BeforeJava25 [ -n "$JDK21" ] && { echo; cr "$JDK21" src/BeforeJava25.java BeforeJava25; } } > "$OUT/02-the-old-workaround.txt" { [ -n "$JDK21" ] && { cr "$JDK21" broken/OnJdk21.java OnJdk21; echo; } cr "$JDK25" broken/OnJdk21.java OnJdk21; echo; cr "$JDK27" broken/OnJdk21.java OnJdk21 } > "$OUT/03-same-file-on-21-25-27.txt" { cr "$JDK25" src/OverridableCall.java OverridableCall; } > "$OUT/04-overridable-call-bug-and-fix.txt" { cr "$JDK25" src/ParseThenSuper.java ParseThenSuper; echo; cr "$JDK25" src/TryInPrologue.java TryInPrologue; echo; cr "$JDK25" src/ThisChaining.java ThisChaining } > "$OUT/05-prologue-in-practice.txt" { o="$B/bc"; mkdir -p "$o"; "$JDK25/bin/javac" -d "$o" src/PrologueBytecode.java 2>&1 echo "\$ javap -c -p 'PrologueBytecode\$Child' ($(v "$JDK25"))"; "$JDK25/bin/javap" -c -p -cp "$o" 'PrologueBytecode$Child' 2>&1 | sed -n '2,$p' } > "$OUT/06-bytecode.txt" # the rules that did not go away: same source, both JDKs, because the wording changed between 25 and 27 { for f in ReadFieldBeforeSuper CallMethodBeforeSuper PassThisBeforeSuper ReadFinalBeforeAssign InnerOuterThis NewInnerBeforeSuper AssignFieldWithInitializer AssignInheritedField ReturnBeforeSuper SuperInBranch TwoSuperCalls; do for j in "$JDK25" "$JDK27"; do echo "\$ javac broken/$f.java ($(v "$j" | sed 's/.*Temurin-//;s/ (build.*//'))" "$j/bin/javac" -d "$B/x" broken/$f.java 2>&1 | grep -E 'error|warning' | sed 's/^broken\///' done; echo done } > "$OUT/07-still-illegal-25-vs-27.txt" # 08 - the language level matters: compiling this source for an older target from JDK 25 { for r in 21 24 25; do echo "\$ javac --release $r broken/OnJdk21.java ($(v "$JDK25" | sed 's/.*Temurin-//;s/ (build.*//'))" "$JDK25/bin/javac" --release $r -d "$B/r$r" broken/OnJdk21.java 2>&1 | grep -v '^Note:' | sed 's/^broken\///'; echo "exit=${PIPESTATUS[0]}"; echo; done } > "$OUT/08-release-levels.txt" echo "wrote $OUT"