Add boot4-migration module: one Boot 3.5.16 service migrated to 4.1.2, with the real compile, start-up, silent and test failures captured at each step

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b4VQVEJWetTT1dYzyJ
This commit is contained in:
2026-10-29 05:57:26 +00:00
co-authored by Claude Sonnet 5.5
parent fd0cf9b527
commit 85074ed51a
45 changed files with 1021 additions and 0 deletions
@@ -0,0 +1,23 @@
$ mvn package # before/ as written: Boot 3.5.16, JDK 25.0.5
CSRFPROBE status=403
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
$ java -jar migration-demo-1.0.0.jar # Boot 3.5.16
GET /summary
{"id":1,"title":"Hello","createdAt":"2026-01-02T03:04:05Z","author":"ankur"} -> HTTP 200
GET /greetings/1
{"id":1,"title":"Hello #1","createdAt":"2026-01-02T03:04:05Z","author":"ankur"} -> HTTP 200
GET /greetings/count
{"rows":3} -> HTTP 200
GET /aspect
{"interceptions":1} -> HTTP 200
GET /gateway
{"client":"DefaultRestClient"} -> HTTP 200
GET /actuator/metrics (first 60 chars)
{"names":["application.ready.time","application.started.time
GET /actuator/health (groups and status only)
groups=None status=UP components=['db', 'diskSpace', 'ping', 'ssl']
GET /actuator/health/liveness
-> HTTP 404
after 40 more requests, log directory holds: 1 app.log; 5 app.log.<date>.<n>.gz; (app.log is 342 bytes; limit set is logging.file.max-size=2KB or its 4.1 replacement)
@@ -0,0 +1,35 @@
$ mvn -DskipTests package # same sources, same pom, only <parent><version> 3.5.16 -> 4.1.2
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-aop:jar is missing. @ line 25, column 17
[ERROR] 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-aop:jar is missing. @ line 25, column 17
# spring-boot-starter-aop has no managed version any more. Rename it to spring-boot-starter-aspectj and try again:
$ mvn compile
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.15.0:compile (default-compile) on project migration-demo: Fatal error compiling: Cannot load from object array because "this.hashes" is null
[INFO] BUILD FAILURE
# Maven's compiler plugin 3.15.0 on JDK 25 crashed inside javac instead of listing the errors, so ask javac directly:
$ javac -cp $(mvn dependency:build-classpath) src/main/java/**/*.java
SecurityConfig.java:3: error: package org.springframework.boot.autoconfigure.security does not exist
import org.springframework.boot.autoconfigure.security.SecurityProperties;
JsonConfig.java:5: error: package com.fasterxml.jackson.core does not exist
import com.fasterxml.jackson.core.JsonGenerator;
JsonConfig.java:6: error: package com.fasterxml.jackson.databind does not exist
import com.fasterxml.jackson.databind.JsonSerializer;
JsonConfig.java:7: error: package com.fasterxml.jackson.databind does not exist
import com.fasterxml.jackson.databind.SerializerProvider;
JsonConfig.java:8: error: cannot find symbol
import org.springframework.boot.jackson.JsonComponent;
JsonConfig.java:12: error: cannot find symbol
public class JsonConfig extends JsonSerializer<Greeting> {
JsonConfig.java:11: error: cannot find symbol
@JsonComponent
JsonConfig.java:14: error: cannot find symbol
public void serialize(Greeting g, JsonGenerator gen, SerializerProvider sp) throws IOException {
JsonConfig.java:14: error: cannot find symbol
public void serialize(Greeting g, JsonGenerator gen, SerializerProvider sp) throws IOException {
SecurityConfig.java:14: error: cannot find symbol
@Order(SecurityProperties.BASIC_AUTH_ORDER)
SecurityConfig.java:16: error: method authorizeHttpRequests in class HttpSecurity cannot be applied to given types;
http.authorizeHttpRequests()
JsonConfig.java:13: error: method does not override or implement a method from a supertype
@Override
javac error count: 12
@@ -0,0 +1,11 @@
$ # s2 = before/ + Boot 4.1.2 + aop->aspectj + JsonConfig and SecurityConfig ported (imports only); every other dependency untouched
$ mvn -DskipTests package
[INFO] BUILD SUCCESS
$ java -jar migration-demo-1.0.0.jar
APPLICATION DID NOT START. The failure report:
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.ankurm.migration.Gateway required a bean of type 'org.springframework.web.client.RestClient$Builder' that could not be found.
Action:
@@ -0,0 +1,25 @@
$ # s3 = s2 + spring-boot-starter-restclient (the only thing the start-up failure asked for). Flyway, properties and the rest still Boot 3 style.
$ mvn -DskipTests package
[INFO] BUILD SUCCESS
$ java -jar migration-demo-1.0.0.jar
GET /summary
{"author":"ankur","createdAt":"2026-01-02T03:04:05Z","id":1,"title":"Hello"} -> HTTP 200
GET /greetings/1
{"id":1,"title":"Hello #1","createdAt":"2026-01-02T03:04:05Z","author":"ankur"} -> HTTP 200
GET /greetings/count
{"timestamp":"2026-10-29T05:55:01.660Z","status":500,"error":"Internal Server Error","path":"/greetings/count"} -> HTTP 500
GET /aspect
{"interceptions":1} -> HTTP 200
GET /gateway
{"client":"DefaultRestClient"} -> HTTP 200
GET /actuator/metrics (first 60 chars)
{"names":["application.ready.time","application.started.time
GET /actuator/health (groups and status only)
groups=['liveness', 'readiness'] status=UP components=['db', 'diskSpace', 'livenessState', 'ping', 'readinessState', 'ssl']
GET /actuator/health/liveness
-> HTTP 200
root cause of that 500 in the application log:
Table "GREETING" not found
Flyway log lines at start-up: 0
after 40 more requests, log directory holds: 1 app.log; (app.log is 54188 bytes; limit set is logging.file.max-size=2KB or its 4.1 replacement)
@@ -0,0 +1,13 @@
$ # s6 = s3 + spring-boot-properties-migrator (runtime scope)
[INFO] BUILD SUCCESS
app started
$ grep -iE 'propert|logging.file|migrat' run.log # what the migrator printed at start-up
WARN 2635 --- [ main] o.s.b.c.p.m.PropertiesMigrationListener :
he use of configuration keys that have been renamed was found in the environment:
Property source 'Config resource 'class path resource [application.properties]' via location 'optional:classpath:/'':
Key: logging.file.max-history
Replacement: logging.logback.rollingpolicy.max-history
Key: logging.file.max-size
Replacement: logging.logback.rollingpolicy.max-file-size
Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.
(lines matching: 3)
@@ -0,0 +1,23 @@
$ mvn verify # after/ : Boot 4.1.2, one starter per technology, -test companions, Jackson 3, new packages
CSRFPROBE status=403
[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
$ java -jar migration-demo-1.0.0.jar
GET /summary
{"author":"ankur","createdAt":"2026-01-02T03:04:05Z","id":1,"title":"Hello"} -> HTTP 200
GET /greetings/1
{"id":1,"title":"Hello #1","createdAt":"2026-01-02T03:04:05Z","author":"ankur"} -> HTTP 200
GET /greetings/count
{"rows":3} -> HTTP 200
GET /aspect
{"interceptions":1} -> HTTP 200
GET /gateway
{"client":"DefaultRestClient"} -> HTTP 200
GET /actuator/metrics (first 60 chars)
{"names":["application.ready.time","application.started.time
GET /actuator/health (groups and status only)
groups=['liveness', 'readiness'] status=UP components=['db', 'diskSpace', 'livenessState', 'ping', 'readinessState', 'ssl']
GET /actuator/health/liveness
-> HTTP 200
after 40 more requests, log directory holds: 1 app.log; 5 app.log.<date>.<n>.gz; (app.log is 513 bytes; limit set is logging.file.max-size=2KB or its 4.1 replacement)
@@ -0,0 +1,4 @@
# GET /summary on the same bean (id, title, createdAt, author declared in that order)
Boot 3.5.16 (Jackson 2): {"id":1,"title":"Hello","createdAt":"2026-01-02T03:04:05Z","author":"ankur"} -> HTTP 200
Boot 4.1.2 (Jackson 3, defaults): {"author":"ankur","createdAt":"2026-01-02T03:04:05Z","id":1,"title":"Hello"} -> HTTP 200
Boot 4.1.2 + spring.jackson.use-jackson2-defaults: {"id":1,"title":"Hello","createdAt":"2026-01-02T03:04:05Z","author":"ankur"} -> HTTP 200
@@ -0,0 +1,6 @@
$ mvn test-compile # after/ pom and main code, but the Boot 3 GreetingControllerTest (@MockBean, old @AutoConfigureMockMvc package)
t1/src/test/java/com/ankurm/migration/GreetingControllerTest.java:[10,63] package org.springframework.boot.test.autoconfigure.web.servlet does not exist
t1/src/test/java/com/ankurm/migration/GreetingControllerTest.java:[12,50] package org.springframework.boot.test.mock.mockito does not exist
t1/src/test/java/com/ankurm/migration/GreetingControllerTest.java:[16,2] cannot find symbol
t1/src/test/java/com/ankurm/migration/GreetingControllerTest.java:[20,6] cannot find symbol
[INFO] BUILD FAILURE
@@ -0,0 +1,5 @@
$ mvn test # after/ pom and main code + the Boot 3 MockFieldTest unchanged (compiles) and CsrfProbeTest (one import fixed)
CSRFPROBE status=403
[ERROR] MockFieldTest.mockFieldIsInitialised:20 @Mock field was never initialised ==> expected: not <null>
[ERROR] Tests run: 2, Failures: 1, Errors: 0, Skipped: 0
[INFO] BUILD FAILURE
@@ -0,0 +1,8 @@
$ javac SecurityConfig.java # Boot 3 file, import repointed to the 4.1.2 package; the old method-chaining DSL left as it was
SecurityConfig.java:16: error: method authorizeHttpRequests in class HttpSecurity cannot be applied to given types;
http.authorizeHttpRequests()
^
required: Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry>
found: no arguments
reason: actual and formal argument lists differ in length
1 error