Repository navigation
Fix compilation failures after Spring Boot 4.x / Jackson 3.x / Spring Security 7 / Hibernate 7 upgrade - #2
Conversation
gortazar
commented
Oct 27, 2026
- upgrade: Spring Boot to 4.0.5 and Java to 21
- Actualizar maven-build.yml
- Add spring-boot-starter-json
- Fix Jackson 3.x migration: update imports and API changes in rest_ejem8, bd_ejem19, comunicacion-ws-ejem2
- Fix compilation failures after Spring Boot 4.x / Jackson 3.x upgrade
- Fix all remaining compilation failures: Jackson 3.x, Hibernate 7, Spring Security 7, Spring Session 4.x, CI workflow
…m8, bd_ejem19, comunicacion-ws-ejem2 Agent-Logs-Url: https://github.com/codeurjc/dad2425/sessions/62560d7f-165d-47e7-ba36-87588d19ffb2 Co-authored-by: gortazar <203272+gortazar@users.noreply.github.com>
Agent-Logs-Url: https://github.com/codeurjc/dad2425/sessions/62560d7f-165d-47e7-ba36-87588d19ffb2 Co-authored-by: gortazar <203272+gortazar@users.noreply.github.com>
…ing Security 7, Spring Session 4.x, CI workflow Agent-Logs-Url: https://github.com/codeurjc/dad2425/sessions/63ada7cb-c19d-454b-9ff6-ea5c62f687b3 Co-authored-by: gortazar <203272+gortazar@users.noreply.github.com>
Spring Boot 4 ships Jackson 3, so com.fasterxml.jackson.databind is gone from the classpath and Jackson2JsonMessageConverter fails at startup with ClassNotFoundException on com.fasterxml.jackson.databind.json.JsonMapper. Spring AMQP 4 provides JacksonJsonMessageConverter as the Jackson 3 equivalent. The ExampleData classes in these projects had already been moved to tools.jackson.databind; only the converter bean was left behind. Verified on Temurin 21: all six compile and their Spring context starts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
H2 treats USER as reserved, so Hibernate's generated DDL failed at startup
in three samples. MySQL accepts it, which is why these ran for years and
only broke on the H2-backed profiles.
Renamed the entity rather than quoting the identifier: a delimited name
would be case-sensitive and would have to be quoted in every hand-written
query, which is a trap for students using the H2 console.
- parte_5/ejem3-cache-distribuida: User -> AppUser
- parte_5/ejem4b-haproxy-ssl-passthrough: User -> AppUser
- parte_2/tema_2.5_db/bd_ejer2: Post.user -> Post.author, since the clash
there is a column, not a table; templates and the form field follow.
In new_post.html only the form field was renamed. The {{#user}} section
there reads the model attribute the controller sets from UserSession,
which is a different thing and still named user. Visible labels are left
untouched.
Verified on Temurin 21: the three compile and their Spring context starts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
spring-cloud-dependencies 2023.0.0 is built for Spring Boot 3.2, so under 4.0.5 the OpenFeign autoconfiguration failed to start looking for org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration, which Boot 4 moved. 2025.1.4 is the current stable train and declares spring-boot.version 4.0.9, checked against its published POM on Maven Central. It is the only project in the branch that imports a Spring Cloud BOM. Verified on Temurin 21: compiles and the Spring context starts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Upgrades every sample to Spring Boot 4.0.5 and Java 21, and fixes the ten VerificationFull sweep of all 85 Maven projects on Temurin 21:
"Start up" means The one remaining failure, What was fixed on top of the upgradeJackson 3 migration left half-done — 6 projects. Spring Boot 4 ships Jackson 3,
In Spring Cloud train too old — 1 project. Known issue, not addressed here
Supersedes codeurjc#2. |
main had moved parte_5/ejem1-mysql to parte_5/ejem1-jmeter/ejem-1 and reorganised the scalability examples, so git flagged the two poms this branch had already bumped. Both conflicts are the same file under a new path: resolved to 4.0.5, the version this branch is standardising on. ejem-2-cache-redis arrived from main at 3.5.12 and was bumped to match. The merged tree now has all 86 poms on Spring Boot 4.0.5 and Java 21. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two separate breakages in ejem1-jmeter/ejem-2-cache-redis, both from the Boot 4 restructuring, found by booting it against real MySQL and Redis containers rather than by compiling it. Boot 4 split autoconfiguration into per-area modules, so spring-boot-starter-data-redis alone no longer contributes the cache autoconfiguration and @EnableCaching found no CacheManager. Added spring-boot-starter-cache. With that in place the next failure was the same Jackson 2 to 3 move as in the AMQP samples: GenericJackson2JsonRedisSerializer is gone from the classpath. Spring Data Redis 4 provides GenericJacksonJsonRedisSerializer, which unlike its predecessor has no no-arg constructor and takes a tools.jackson.databind.ObjectMapper. Verified on Temurin 21: starts in 5s against mysql:8.0 and redis:alpine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Merged
|
| Count | |
|---|---|
| Projects | 86 |
| Compile | 86 |
| Start up | 75 (72 from the sweep + these 3 by hand) |
| Fail | 0 |
| Skipped | 11 (need MySQL from docker-compose) |
parte_5/ejem0-jmeter is in the skipped group: it takes its datasource URL from
docker-compose, so it cannot start standalone. It is not a regression.
Still open, unrelated to this upgrade
parte_2/tema_2.5_db/bd_ejem17 declares querydsl-apt as provided with no
annotationProcessorPaths, relying on implicit annotation processing. That works
on Java 21 but JDK 23 and later no longer run processors found on the classpath,
so QPost silently stops being generated. Worth fixing before the next JDK bump.
Nothing in this branch was covered by a test: only one of the 86 projects shipped any, so "it compiles" was the whole guarantee behind the Spring Boot 4 upgrade. Every project now has a SmokeTest that boots it. Three shapes, picked per project: - Spring Boot apps with no external service: @SpringBootTest, which fails if any bean cannot be created. That is what caught the Jackson 3 and autoconfiguration breakage earlier in this branch. - Apps backed by MySQL, RabbitMQ or Redis: Testcontainers via @Serviceconnection, plus a test that opens the connection and checks it answers. 21 projects, with real containers. - parte_4/tema_4.2/ejemplo-2 is a plain command-line program with no Spring: it runs main() and asserts the arguments come out. JUnit and surefire are declared there by hand, since that pom has no Boot parent. Three projects needed more than the test itself: - parte_4/tema_4.3/ejemplo-{2,3} have a second @SpringBootConfiguration (DatabaseWaitConfigurator), so the test says classes = WebApp.class instead of letting the search find two candidates. - parte_2/tema_2.6_despliegue/despliegue_ejem2 defaults to the dev profile, which pins H2Dialect. @Serviceconnection replaces the URL and the credentials but not the dialect, so Hibernate emitted sequence DDL against MySQL. The test runs under the prod profile instead. parte_5/ejem0-jmeter had an Ejem0EmployeeApplicationTests doing contextLoads() against a database that only exists under docker-compose, so it could never pass on its own. The new SmokeTest replaces it and brings its own container. Verified on Temurin 21: mvn clean verify on all 86 projects, 86 green, 132 tests, 21 of them against real containers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The matrix was 86 paths written out one by one, and it went stale as soon as parte_5 was reorganised: the last run failed on a working directory that no longer existed, not on any code. A discover job now derives the list from git ls-files, so moving or adding a project needs no edit here. Using git ls-files rather than find keeps generated poms under target/ out of the list. It refuses to continue on zero projects, and on more than 256, which is the matrix limit GitHub enforces. Two other things were wrong in this file: - The branch filter was '*', which does not match a branch name with a slash in it. Pushes to copilot/update-springboot-java-versions never triggered a run; what did run came in as a pull_request event, whose filter applies to the base branch. It is '**' now. - The build ran mvn clean package -DskipTests, so the tests added in the previous commit would never have run in CI. It is mvn clean verify. A result job gates the whole matrix, so branch protection has one check to require instead of 86 names that change. Added concurrency cancel-in-progress: one push is 86 jobs, and there is no point finishing a run whose commit is already superseded. Drop that block if you would rather keep every run. Verified: the discovery pipeline returns the same 86 projects the hand written matrix listed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Smoke tests on every project, and a CI matrix that discovers themTwo commits on top of the previous report.
|
| Project | Problem | Fix |
|---|---|---|
parte_4/tema_4.3/ejemplo-2 |
Two @SpringBootConfiguration classes (WebApp plus DatabaseWaitConfigurator) |
@SpringBootTest(classes = WebApp.class) |
parte_4/tema_4.3/ejemplo-3 |
same | same |
parte_2/tema_2.6_despliegue/despliegue_ejem2 |
The dev profile pins H2Dialect; @ServiceConnection replaces the URL and credentials but not the dialect, so Hibernate emitted sequence DDL against MySQL |
The test runs under the prod profile |
parte_5/ejem0-jmeter had an Ejem0EmployeeApplicationTests running contextLoads() against a database that only exists under docker-compose, so it could never pass on its own. The new SmokeTest replaces it and brings its own container.
f061417 — CI discovers the projects
The matrix was 86 paths written out by hand, and it went stale as soon as parte_5 was reorganised: run 40696456183 failed on a working directory that no longer existed, not on any code. A discover job now derives the list from git ls-files, so moving or adding a project needs no edit to the workflow. git ls-files rather than find, to keep generated poms under target/ out of the list.
Two other things were wrong in that file:
- The branch filter was
'*', which does not match a branch name containing a slash. Pushes to this branch never triggered a run; what did run arrived as apull_requestevent, whose filter applies to the base branch. It is'**'now. - The build ran
mvn clean package -DskipTests, so the tests above would never have run in CI. It ismvn -B -ntp clean verify.
A result job gates the matrix, so branch protection has one stable check to require instead of 86 names that change.
Local verification
mvn clean verify on all 86 projects with Temurin 21:
| Projects | 86 |
| Green | 86 |
| Tests run | 132 |
| Against real containers | 21 |
Still open, unrelated to this upgrade
parte_2/tema_2.5_db/bd_ejem17 declares querydsl-apt as provided without annotationProcessorPaths. It works on Java 21, but from JDK 23 on javac no longer runs annotation processors found on the classpath, so QPost silently stops being generated.