#!/usr/bin/env bash # Docker layer arithmetic without a Docker daemon: which layers of the extracted application change when one line of # code changes, how big each layer is (uncompressed, and gzipped as a registry would store it), and where the AOT # cache falls. A layer is "a directory tree"; two builds share a layer when the tree is byte-identical. source "$(dirname "$0")/env.sh" cd "$ROOT" layer_sum() { # dir -> one hash over every file's path and contents ( cd "$1" && find . -type f | LC_ALL=C sort | xargs sha256sum | sha256sum | cut -c1-12 ) } gz_kb() { tar -C "$1" -cf - . 2>/dev/null | gzip -6 | wc -c | awk '{printf "%d", $1/1024}'; } kb() { find "$1" -type f -printf '%s\n' | awk '{s+=$1} END{printf "%d", s/1024}'; } echo "# java -Djarmode=tools -jar app.jar extract --layers (the layer order Spring Boot's Dockerfile support uses)" rm -rf "$WORK/layers-a" "$WORK/layers-b" "$JDK25/bin/java" -Djarmode=tools -jar "$WORK/app.jar" extract --layers --destination "$WORK/layers-a" >/dev/null printf '%-22s %10s %10s %s\n' layer "KB" "gzip KB" "files" for d in dependencies spring-boot-loader snapshot-dependencies application; do printf '%-22s %10s %10s %s\n' "$d" "$(kb "$WORK/layers-a/$d")" "$(gz_kb "$WORK/layers-a/$d")" "$(find "$WORK/layers-a/$d" -type f | wc -l)" done echo echo "# the AOT cache from the training run (context-only), for scale" printf '%-22s %10s %10s\n' "refresh.aot" "$(( $(stat -c %s "$WORK/refresh.aot") / 1024 ))" "$(gzip -6 -c "$WORK/refresh.aot" | wc -c | awk '{printf "%d", $1/1024}')" echo echo "# change one line of application code (the unit price in OrderService, built by prepare.sh), extract again" "$JDK25/bin/java" -Djarmode=tools -jar "$WORK/app-changed.jar" extract --layers --destination "$WORK/layers-b" >/dev/null printf '%-22s %-14s %-14s %s\n' layer "before" "after" "verdict" for d in dependencies spring-boot-loader snapshot-dependencies application; do a=$(layer_sum "$WORK/layers-a/$d"); b=$(layer_sum "$WORK/layers-b/$d") printf '%-22s %-14s %-14s %s\n' "$d" "$a" "$b" "$([ "$a" = "$b" ] && echo "identical: reused from cache/registry" || echo "CHANGED: rebuilt and pushed")" done echo "AOT cache: trained against the previous jar, so it is stale for the new one (see output/04-mismatch.txt); it must be regenerated after the application layer"