Files

82 lines
6.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Facts about the Jakarta EE 11 API jars, read from Maven Central artifacts and Spring Boot's own BOM. No running application.
set -uo pipefail
cd "$(dirname "$0")/.."
R="$HOME/.m2/repository"; W=$(mktemp -d); CEN=https://repo1.maven.org/maven2
get() { mvn -B -q dependency:get -Dartifact="$1" >/dev/null 2>&1; }
jar() { echo "$R/$(echo "$1" | cut -d: -f1 | tr . /)/$2/$3/$2-$3.jar"; }
# --- 01: what Spring Boot 4.1.1 manages -------------------------------------------------------------------
for i in 1 2 3 4 5; do code=$(curl -s -o "$W/bom.pom" -w '%{http_code}' $CEN/org/springframework/boot/spring-boot-dependencies/4.1.1/spring-boot-dependencies-4.1.1.pom); [ "$code" = 200 ] && break; sleep $((i*3)); done
{
echo "# 01-boot-managed-jakarta-apis (spring-boot-dependencies 4.1.1)"
grep -E '<(jakarta-[a-z-]+|tomcat|jetty|hibernate|hibernate-validator|spring-data-bom|spring-framework)\.version>' "$W/bom.pom" | sed 's/^ *//; s/<\([^>]*\)>\(.*\)<\/.*/\1 = \2/' | sort
echo "--- artifacts NOT in the BOM (0 = Spring Boot does not manage them)"
for a in jakarta.data-api jakarta.enterprise.concurrent-api jakarta.enterprise.cdi-api jakarta.security.enterprise-api jakarta.faces-api jakarta.ws.rs-api; do
printf ' %-36s %s\n' "$a" "$(grep -c "<artifactId>$a</artifactId>" "$W/bom.pom")"
done
} > output/01-boot-managed-jakarta-apis.txt
# --- 02: API differences between the EE 10 and EE 11 versions of four specs ---------------------------------
diffspec() { # name group artifact old new
get "$2:$3:$4"; get "$2:$3:$5"
for v in $4 $5; do
j=$(jar "$2" "$3" "$v"); rm -rf "$W/x-$v"; mkdir -p "$W/x-$v"; unzip -q -o "$j" '*.class' -d "$W/x-$v" 2>/dev/null
( cd "$W/x-$v" && find . -name '*.class' ! -name 'module-info.class' | sed 's#^\./##; s#\.class$##; s#/#.#g' | sort > "$W/cls-$v.txt"
javap -public -cp . $(cat "$W/cls-$v.txt" | grep -v 'package-info') 2>/dev/null | grep -E '^\s+(public|protected)|^(public|protected)' | sed 's/^ *//' | sort -u > "$W/mem-$v.txt" )
done
echo "--- $1: $3 $4 -> $5"
echo " classes added : $(comm -13 "$W/cls-$4.txt" "$W/cls-$5.txt" | wc -l) removed: $(comm -23 "$W/cls-$4.txt" "$W/cls-$5.txt" | wc -l)"
echo " members added : $(comm -13 "$W/mem-$4.txt" "$W/mem-$5.txt" | wc -l) removed: $(comm -23 "$W/mem-$4.txt" "$W/mem-$5.txt" | wc -l)"
comm -13 "$W/cls-$4.txt" "$W/cls-$5.txt" | sed 's/^/ + class /' | head -12
comm -23 "$W/cls-$4.txt" "$W/cls-$5.txt" | sed 's/^/ - class /' | head -12
}
{
echo "# 02-api-diff (javap -public over every class of the two jars; members are signature strings, so a changed signature counts as one removed and one added)"
diffspec Servlet jakarta.servlet jakarta.servlet-api 6.0.0 6.1.0
diffspec Persistence jakarta.persistence jakarta.persistence-api 3.1.0 3.2.0
diffspec Validation jakarta.validation jakarta.validation-api 3.0.0 3.1.0
diffspec Annotations jakarta.annotation jakarta.annotation-api 2.1.1 3.0.0
diffspec Concurrency jakarta.enterprise.concurrent jakarta.enterprise.concurrent-api 3.0.0 3.1.1
} > output/02-api-diff.txt
# --- 03: the new Persistence 3.2 EntityManager methods, by name --------------------------------------------
{
echo "# 03-entitymanager-3.2 (methods on jakarta.persistence.EntityManager that 3.1.0 did not have)"
for v in 3.1.0 3.2.0; do javap -public -cp "$(jar jakarta.persistence jakarta.persistence-api $v)" jakarta.persistence.EntityManager 2>/dev/null | grep '(' | sed 's/^ *//; s/jakarta.persistence.//g; s/java.lang.//g; s/java.util.//g' | sort > "$W/em-$v.txt"; done
comm -13 "$W/em-3.1.0.txt" "$W/em-3.2.0.txt"
} > output/03-entitymanager-3.2.txt
# --- 04: Jakarta Data 1.0 API surface and the virtual-thread switch in Concurrency 3.1 ---------------------
get jakarta.data:jakarta.data-api:1.0.2
{
echo "# 04-data-and-concurrency"
echo "--- jakarta.data-api 1.0.2: types in jakarta.data.repository"
unzip -l "$(jar jakarta.data jakarta.data-api 1.0.2)" | awk '{print $4}' | grep -E '^jakarta/data/repository/[A-Z][A-Za-z]*\.class$' | sed 's#jakarta/data/repository/##; s#\.class##' | sort | sed 's/^/ /'
for v in 3.0.0 3.1.1; do
echo "--- jakarta.enterprise.concurrent-api $v: attributes of @ManagedExecutorDefinition"
javap -public -cp "$(jar jakarta.enterprise.concurrent jakarta.enterprise.concurrent-api $v)" jakarta.enterprise.concurrent.ManagedExecutorDefinition 2>/dev/null | grep '()' | sed 's/^ *//; s/public abstract //; s/java.lang.//g' | sed 's/^/ /'
done
} > output/04-data-and-concurrency.txt
# --- 06: does the Spring Data version Boot manages contain any Jakarta Data code? ---------------------------
{
echo "# 06-spring-data-and-jakarta-data (classes mentioning jakarta/data inside Spring Data jars from Spring Data 2026.0.1)"
for a in spring-data-commons spring-data-jpa; do
v=$(curl -s $CEN/org/springframework/data/$a/maven-metadata.xml | grep -o '<version>4\.[0-9.]*</version>' | tail -1 | sed 's/<[^>]*>//g')
get org.springframework.data:$a:$v
j="$R/org/springframework/data/$a/$v/$a-$v.jar"
n=$(unzip -l "$j" 2>/dev/null | grep -c 'jakarta/data/')
m=$(unzip -p "$j" 2>/dev/null META-INF/MANIFEST.MF | grep -c 'jakarta.data')
echo " $a $v: entries under jakarta/data/: $n; manifest lines mentioning jakarta.data: $m"
done
} > output/06-spring-data-and-jakarta-data.txt
# --- 07: Spring Boot's own switch for virtual threads (read from the shipped configuration metadata) ----------
get org.springframework.boot:spring-boot-autoconfigure:4.1.1
{
echo "# 07-virtual-threads-property (spring-boot-autoconfigure 4.1.1 configuration metadata)"
unzip -p "$(jar org.springframework.boot spring-boot-autoconfigure 4.1.1)" META-INF/spring-configuration-metadata.json \
| python3 -c "import json,sys; [print(p['name'], '(' + p.get('type','?') + ', default ' + str(p.get('defaultValue','none')) + '):', p.get('description','')) for p in json.load(sys.stdin)['properties'] if p['name']=='spring.threads.virtual.enabled']"
} > output/07-virtual-threads-property.txt