Files
javademos/jep511/run.sh
T
Claude 96b25c8fc4 jep511: add the star-import clash demo, java.base export count and a java.time jshell check
TwoStarImports.java, the java.base export count in output/04, the extra LocalDate line in src/imports.jsh and regenerated transcripts. Additive commit.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
2026-09-24 11:42:45 +00:00

90 lines
6.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# JEP 511 (Module Import Declarations): 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"
# the build string of a JDK, e.g. 25.0.4.1+1-LTS
t() { "$1/bin/java" -version 2>&1 | sed -n 2p | sed 's/.*(build \(.*\))/\1/'; }
# compile SRC (extra javac args in $EXTRA) and run CLASS; header names the JDK
cr() { local jdk="$1" src="$2" cls="$3"; shift 3; local o; o="$(mktemp -d -p "$B")"
echo "\$ javac ${*:+$* }$src && java $cls ($(t "$jdk"))"
"$jdk/bin/javac" "$@" -d "$o" "$src" 2>&1 && "$jdk/bin/java" "$@" -cp "$o" "$cls" 2>&1; }
# compile only: shows the diagnostics
co() { local jdk="$1" src="$2"; shift 2; local o; o="$(mktemp -d -p "$B")"
echo "\$ javac ${*:+$* }$src ($(t "$jdk"))"
"$jdk/bin/javac" "$@" -d "$o" "$src" 2>&1 | grep -v '^Note:'; }
both() { local fn="$1"; shift; "$fn" "$JDK25" "$@"; echo; "$fn" "$JDK27" "$@"; }
# 01 - the same program with one import line instead of seven
{ both cr src/OldWay.java OldWay; echo; both cr src/NewWay.java NewWay; } > "$OUT/01-old-vs-new.txt"
# 02 - ambiguity: two modules export a class with the same simple name
{ both co broken/AmbiguousDate.java; echo; both co broken/AmbiguousList.java; echo; both co broken/TwoStarImports.java; echo; both cr src/FixedDate.java FixedDate; } > "$OUT/02-ambiguity.txt"
# 03 - precedence: who wins when several imports offer the same simple name
{ both cr src/StarImportWins.java StarImportWins; echo; both cr src/StarImportWinsSql.java StarImportWinsSql; echo
both cr src/SamePackageWins.java SamePackageWins; echo; both cr src/UnusedAmbiguity.java UnusedAmbiguity; echo
both cr src/DuplicateImports.java DuplicateImports; } > "$OUT/03-precedence.txt"
# 04 - what one module import actually brings in
{ echo "\$ java --describe-module java.base | grep -c '^exports' ($(t "$JDK25"))"; "$JDK25/bin/java" --describe-module java.base | grep -c '^exports'; echo
echo "\$ java --describe-module java.sql ($(t "$JDK25"))"; "$JDK25/bin/java" --describe-module java.sql; echo
echo "\$ java --describe-module java.se | grep -c 'requires' ($(t "$JDK25"))"; "$JDK25/bin/java" --describe-module java.se | grep -c requires; echo
echo "\$ java --describe-module java.se | grep -c exports ($(t "$JDK25"))"; "$JDK25/bin/java" --describe-module java.se | grep -c exports; echo
both cr src/Transitive.java Transitive; echo; both co broken/SqlDoesNotGiveBase.java; echo
both co src/JavaSe.java; echo; both cr src/JavaSe.java JavaSe --add-modules java.se; } > "$OUT/04-what-a-module-import-brings-in.txt"
# 05 - packages, named modules and library modules
{ both cr src/InPackage.java demo.mod.InPackage; echo
for j in "$JDK25" "$JDK27"; do o="$(mktemp -d -p "$B")"
echo "\$ javac -d out --module-source-path multi --module acme.text,demo.app && java -p out -m demo.app/demo.App ($(t "$j"))"
"$j/bin/javac" -d "$o" --module-source-path multi --module acme.text,demo.app 2>&1 && "$j/bin/java" -p "$o" -m demo.app/demo.App 2>&1; echo
echo "\$ javac -d out --module-source-path multi --module acme.text,demo.bad ($(t "$j"))"
"$j/bin/javac" -d "$(mktemp -d -p "$B")" --module-source-path multi --module acme.text,demo.bad 2>&1; echo
echo "\$ javac -d out --module-source-path multi --module demo.noreq ($(t "$j"))"
"$j/bin/javac" -d "$(mktemp -d -p "$B")" --module-source-path multi --module demo.noreq 2>&1; echo
done
lib="$(mktemp -d -p "$B")"; "$JDK25/bin/javac" -d "$lib" --module-source-path multi --module acme.text 2>&1
c="$(mktemp -d -p "$B")"
echo "\$ javac -p lib src/ThirdParty.java ($(t "$JDK25"))"; "$JDK25/bin/javac" -p "$lib" -d "$c" src/ThirdParty.java 2>&1; echo
echo "\$ javac -p lib --add-modules acme.text src/ThirdParty.java && java -p lib --add-modules acme.text -cp out ThirdParty ($(t "$JDK25"))"
"$JDK25/bin/javac" -p "$lib" --add-modules acme.text -d "$c" src/ThirdParty.java 2>&1 && "$JDK25/bin/java" -p "$lib" --add-modules acme.text -cp "$c" ThirdParty 2>&1
} > "$OUT/05-packages-and-modules.txt"
# 06 - together with JEP 512 compact source files, and in the source launcher
{ both cr src/CompactNoImport.java CompactNoImport; echo; both cr src/CompactPlusImport.java CompactPlusImport; echo
both co src/CompactAmbiguous.java; echo; both co broken/ClassicNoImport.java; echo
for j in "$JDK25" "$JDK27"; do echo "\$ java src/Script.java ($(t "$j"))"; "$j/bin/java" src/Script.java 2>&1; echo; done
} > "$OUT/06-compact-files-and-scripts.txt"
# 07 - what the compiler emits: nothing different
{ o="$(mktemp -d -p "$B")"; "$JDK25/bin/javac" -d "$o" src/OldWay.java src/NewWay.java
for c in OldWay NewWay; do "$JDK25/bin/javap" -c -p -cp "$o" "$c" | sed "s/$c/X/g" | grep -v '^Compiled from' > "$o/$c.txt"; done
echo "\$ diff <(javap -c -p OldWay) <(javap -c -p NewWay) ($(t "$JDK25"), class name normalised to X)"
diff "$o/OldWay.txt" "$o/NewWay.txt" && echo "no differences ($(wc -l < "$o/OldWay.txt") lines of javap output each)"; echo
echo "\$ cmp OldWay.class NewWay.class (javac -g:none; NewWay renamed to OldWay inside the class file)"
"$JDK25/bin/javac" -g:none -d "$o/n" src/OldWay.java src/NewWay.java
LC_ALL=C sed 's/NewWay/OldWay/g' "$o/n/NewWay.class" > "$o/NewWay.renamed"
cmp "$o/n/OldWay.class" "$o/NewWay.renamed" && echo "identical, byte for byte ($(stat -c %s "$o/n/OldWay.class") bytes)"
for c in OldWay NewWay; do "$JDK25/bin/javap" -c -p -l -cp "$o" "$c" | sed "s/$c/X/g" | grep -v '^Compiled from' > "$o/$c.l"; done
echo; echo "\$ diff <(javap -c -p -l OldWay) <(javap -c -p -l NewWay) (default javac -g keeps line numbers)"
diff "$o/OldWay.l" "$o/NewWay.l"
} > "$OUT/07-bytecode-identical.txt"
# 08 - errors that are not about ambiguity, and the language level
{ both co broken/NoSuchModule.java; echo; both co broken/ModuleInsideClass.java; echo
for r in 21 24 25; do echo "\$ javac --release $r src/NewWay.java ($(t "$JDK25"))"
"$JDK25/bin/javac" --release $r -d "$(mktemp -d -p "$B")" src/NewWay.java 2>&1; echo "exit=$?"; echo; done
[ -n "$JDK21" ] && co "$JDK21" src/NewWay.java; } > "$OUT/08-errors-and-release-levels.txt"
# 09 - jshell: what it imports for you
{ for j in ${JDK21:+"$JDK21"} "$JDK25" "$JDK27"; do
"$j/bin/jshell" --feedback concise src/imports.jsh >/dev/null 2>&1 # first run creates the prefs dir and logs about it
echo "\$ jshell --feedback concise src/imports.jsh ($(t "$j"))"; "$j/bin/jshell" --feedback concise src/imports.jsh 2>&1; echo; done
} > "$OUT/09-jshell.txt"
echo "wrote $OUT"