97 lines
4.8 KiB
Bash
97 lines
4.8 KiB
Bash
#!/usr/bin/env bash
|
|
# Facts that come from the shipped jars and their sources rather than from running the scenarios:
|
|
# 15 SpringApplication.run / callRunners / EventPublishingRunListener, read from the 4.1.2 sources jar,
|
|
# and the same method in Boot 3.0.13 and 3.1.12 for contrast
|
|
# 16 the same method read out of the compiled 4.1.2 class with javap (what it really calls)
|
|
# 17 DefaultLifecycleProcessor: when start() and stop() are called
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
mkdir -p output target/facts
|
|
BOOT=4.1.2
|
|
SPRING=7.0.10
|
|
M2=~/.m2/repository
|
|
|
|
fetch() { # url, destination: Maven Central rate-limits shared addresses, so retry politely
|
|
for i in 1 2 3 4 5 6; do
|
|
code=$(curl -s -o "$2" -w '%{http_code}' "$1" || true)
|
|
[ "$code" = 200 ] && return 0
|
|
sleep $((i * 10))
|
|
done
|
|
echo "could not fetch $1 (last status $code)" >&2; return 1
|
|
}
|
|
src() { # groupPath artifact version
|
|
local f="target/facts/$2-$3-sources.jar"
|
|
[ -s "$f" ] || fetch "https://repo1.maven.org/maven2/$1/$2/$3/$2-$3-sources.jar" "$f"
|
|
echo "$f"
|
|
}
|
|
method() { # sources-jar file-in-jar start-regex -> prints from the first match to the first line that is a single tab + }
|
|
unzip -p "$1" "$2" | sed -n "/$3/,/^ }/p"
|
|
}
|
|
|
|
BOOT_SRC=$(src org/springframework/boot spring-boot $BOOT)
|
|
OLD0=$(src org/springframework/boot spring-boot 3.0.13)
|
|
OLD1=$(src org/springframework/boot spring-boot 3.1.12)
|
|
FW_SRC=$(src org/springframework spring-context $SPRING)
|
|
APP=org/springframework/boot/SpringApplication.java
|
|
|
|
{
|
|
echo "# Spring Boot $BOOT sources: the order SpringApplication.run() calls things in, and callRunners"
|
|
echo
|
|
echo "--- SpringApplication.run(): from refresh to ready (lines containing the calls) ---"
|
|
unzip -p "$BOOT_SRC" $APP | sed -n '/public ConfigurableApplicationContext run(String... args)/,/^ }/p' \
|
|
| grep -n -E 'refreshContext|afterRefresh|listeners\.(started|ready)|callRunners|handleRunFailure' | sed 's/^\([0-9]*\):\s*/\1: /'
|
|
echo
|
|
echo "--- SpringApplication.callRunners ---"
|
|
method "$BOOT_SRC" $APP 'private void callRunners'
|
|
echo
|
|
echo "--- SpringApplication.callRunner (what happens to a bean that is both kinds) ---"
|
|
method "$BOOT_SRC" $APP 'private void callRunner(Runner runner'
|
|
echo
|
|
echo "--- SpringApplication.callRunner(Class, Runner, ThrowingConsumer) (where 'Failed to execute' comes from) ---"
|
|
method "$BOOT_SRC" $APP 'private <R extends Runner> void callRunner'
|
|
echo
|
|
echo "--- EventPublishingRunListener.started / ready ---"
|
|
method "$BOOT_SRC" org/springframework/boot/context/event/EventPublishingRunListener.java 'public void started'
|
|
method "$BOOT_SRC" org/springframework/boot/context/event/EventPublishingRunListener.java 'public void ready'
|
|
echo
|
|
echo "--- the marker interface that both runners extend ---"
|
|
unzip -p "$BOOT_SRC" org/springframework/boot/Runner.java | grep -E '^(interface|public interface)'
|
|
unzip -p "$BOOT_SRC" org/springframework/boot/CommandLineRunner.java | grep -E '^public interface'
|
|
unzip -p "$BOOT_SRC" org/springframework/boot/ApplicationRunner.java | grep -E '^public interface'
|
|
echo
|
|
echo "--- the same method in Spring Boot 3.0.13 ---"
|
|
method "$OLD0" $APP 'private void callRunners'
|
|
echo
|
|
echo "--- the same method in Spring Boot 3.1.12 ---"
|
|
method "$OLD1" $APP 'private void callRunners'
|
|
} > output/15-callrunners-source.txt
|
|
|
|
JAR=$(find "$M2/org/springframework/boot/spring-boot/$BOOT" -name "spring-boot-$BOOT.jar" | head -1)
|
|
{
|
|
echo "# javap -p -c on spring-boot-$BOOT.jar: the compiled SpringApplication.callRunners"
|
|
echo
|
|
echo "--- javap -p org.springframework.boot.Runner / CommandLineRunner / ApplicationRunner ---"
|
|
javap -p -cp "$JAR" org.springframework.boot.Runner org.springframework.boot.CommandLineRunner org.springframework.boot.ApplicationRunner
|
|
echo
|
|
echo "--- invoke* instructions inside callRunners ---"
|
|
javap -p -c -cp "$JAR" org.springframework.boot.SpringApplication \
|
|
| sed -n '/private void callRunners(/,/^$/p' | grep -E 'invoke|new ' | sed 's/^ *[0-9]*: //'
|
|
} > output/16-javap-callrunners.txt
|
|
|
|
CTX=$(find "$M2/org/springframework/spring-context/$SPRING" -name "spring-context-$SPRING.jar" | head -1)
|
|
LP=org/springframework/context/support/DefaultLifecycleProcessor.java
|
|
{
|
|
echo "# spring-context $SPRING sources: DefaultLifecycleProcessor, the object that starts and stops SmartLifecycle beans"
|
|
echo
|
|
echo "--- doStart: start() is called only when isRunning() is false ---"
|
|
method "$FW_SRC" $LP 'private void doStart(Map'
|
|
echo
|
|
echo "--- doStop: stop() is called only when isRunning() is true ---"
|
|
method "$FW_SRC" $LP 'private void doStop(Map'
|
|
echo
|
|
echo "--- isAutoStartupCandidate / toBeStarted: what isAutoStartup() decides ---"
|
|
method "$FW_SRC" $LP 'private boolean isAutoStartupCandidate'
|
|
method "$FW_SRC" $LP 'private boolean toBeStarted'
|
|
} > output/17-lifecycleprocessor-source.txt
|
|
ls -1 output | tail -3
|