Spring Boot 3 and 4
ElastiCORE 3.0 supports Spring Boot 3 and Spring Boot 4 (2.2 supports Spring Boot 3 only). Checked with Spring Boot 4.0.8, Spring AI 2.0.1, Hibernate 7.2, Spring Data JPA 4.0, Jackson 3.1; the Spring Boot 3 runtime library is tested on 3.5.16.
| Spring Boot 3 | Spring Boot 4 | |
|---|---|---|
| Runtime library | io.elasticore.springboot3:elasticore-springboot3 | io.elasticore.springboot4:elasticore-springboot4 |
| Java package of the runtime | io.elasticore.springboot3 | io.elasticore.springboot3 (the same - generated imports do not change) |
| Web starter | spring-boot-starter-web | spring-boot-starter-webmvc |
| springdoc | 2.8.17 | 3.0.3 |
| Gradle | 8.14 or later | |
| Kotlin | 2.2 or later; Jackson module tools.jackson.module:jackson-module-kotlin |
Moving a project from Boot 3 to 4 changes the Boot plugin's version, the runtime library line, the web starter and springdoc; the generated imports do not change.
What the generator does on its own
The plugin reads the version of the Spring Boot Gradle plugin applied to the build (an
apply false declaration in the root is enough). On Boot 4 the generated code changes where it has
to:
| Generated | Spring Boot 3 | Spring Boot 4 |
|---|---|---|
enums (@json) | Jackson 2 CustomSerializer / CustomDeserializer | @JsonValue + @JsonCreator (Jackson 2 and 3) |
| outbox recorder (DDD) | Jackson 2 ObjectMapper | Jackson 3 JsonMapper |
| Kotlin | as is | T : Any on Specification type parameters, !! on Page.map (Spring Data 4's JSpecify) |
| HTTP port client (runtime) | Jackson 2 codec | Jackson 3 codec |
HTTP port (optional httpPort: spring) | ElastiCORE runtime | a Spring @HttpExchange interface + @ImportHttpServices |
| entities, repositories, services, controllers | as is | as is |
Why enums have to change: Spring Boot 4's web layer writes JSON with Jackson 3, which does not
look at Jackson 2's @JsonSerialize / @JsonDeserialize. An enum written for Boot 3 would go out
without an error by its name ("DRAFT") instead of its code ("DRF").
The decided version is the first line of the generation log:
[ElastiCORE] Spring Boot: 4.0.8 (build) - enums and the outbox are written for Jackson 3
If a Boot 4 project shows Spring Boot: 3, say it:
| Where | How | When |
|---|---|---|
build.gradle | elasticore { springBoot = '4' } | the plugin cannot read it (a BOM without the Boot plugin, an older Gradle) |
env.yml | elasticore: config: springBoot: 4 | generating without the plugin |
| JavaExec | systemProperty 'elasticore.springBoot', '4' | a generation task of your own |
The pet store sample says springBoot = '4': its build's Gradle predates the Boot 4 plugin, so the
version cannot be read off it.
What you change yourself
Code ElastiCORE did not write follows the Spring Boot 4 migration guide. What the samples needed:
| Symptom | Fix |
|---|---|
package org.springframework.boot.test.autoconfigure.web.servlet does not exist | org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc + spring-boot-starter-webmvc-test |
No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' | tools.jackson.databind.ObjectMapper (Boot 4 registers a Jackson 3 mapper) |
JsonNode.asText() warning | Jackson 3: asString() |
Generate-once files you already own (XxxService, controllers) are not regenerated.
Spring AI
supportAI: "true" in env.yml puts Spring AI @Tool / @ToolParam on the generated service
methods (the same annotations in Spring AI 1.x and 2.0). On Boot 4 with Spring AI 2.0:
implementation platform('org.springframework.ai:spring-ai-bom:2.0.1')
implementation 'org.springframework.ai:spring-ai-model'
@Bean
ToolCallbackProvider erpTools(PartnerService partners, ItemService items) {
return MethodToolCallbackProvider.builder().toolObjects(partners, items).build();
}
A @readonly entity, or a method removed with @restExclude, gets read tools only.