Spring boot 4.1.0 migration#358
Conversation
| private static String brokersAsString(EmbeddedKafkaBroker value) { | ||
| try { | ||
| return value.getBrokersAsString(); | ||
| } catch (RuntimeException e) { |
There was a problem hiding this comment.
Is it needed to catch RuntimeException ? is IllegalArgumentException not enough ?
There was a problem hiding this comment.
EmbeddedKafkaBroker.getBrokersAsString() throws a RuntimeException when the broker has been shut down (the Kafka broker is no longer
running), so catching it and returning "shut down" can be the correct defensive fallback for serialization purposes
| broker.destroy(); | ||
| return ActionExecutionResult.ok(); | ||
| } catch (Exception e) { | ||
| logger.error("Kafka broker shutdown failed: " + e.getMessage()); |
There was a problem hiding this comment.
Maybe we should log the stack trace.
Why should we throw this large scope : Exception ?
There was a problem hiding this comment.
destroy() throws Exception in DisposableBean interface
There was a problem hiding this comment.
Well, I think there is EmbeddedKafkaBroker which overrides destroy() method without throwing Exception.
Not blocking for me
- Bump springboot.version 3.5.11 → 4.0.6 (Spring Framework 7.x) - Bump Kotlin 1.9.25 → 2.2.0 (required by SB4); update compiler/api version - Bump testcontainers BOM 2.0.4 → 2.0.5 Undertow removal (dropped in SB4 / Servlet 6.1): - Replace spring-boot-starter-undertow with spring-boot-starter-tomcat - Rewrite UndertowConfig.java as TomcatServletWebServerFactory customizer preserving HTTP→HTTPS redirect on port 80→443 via SecurityConstraint - Rename profile undertow-https-redirect → https-redirect in application.yml files Starter renames (SB4 modular naming): - spring-boot-starter-web → spring-boot-starter-webmvc - spring-boot-starter-oauth2-resource-server → spring-boot-starter-security-oauth2-resource-server - spring-security-test → spring-boot-starter-security-test - Add spring-boot-properties-migrator (runtime, temporary) - Remove <executable>true</executable> from spring-boot-maven-plugin (launch scripts dropped) Jackson 3 (group ID change com.fasterxml.jackson → tools.jackson): - Update all sub-module poms: server, jira, engine, tools, action-impl, kotlin-dsl - Remove jackson-datatype-jdk8 (merged into Jackson 3 core) - Update BrokerMQModule and BrokerServiceSerializer imports - Update Scala module exclusion to tools.jackson.module group WSS4J 1.6.19 → 3.0.4 (Jakarta EE 11 compatible): - Change groupId org.apache.ws.security:wss4j → org.apache.wss4j:wss4j-ws-security-dom - Bump Apache Santuario xmlsec 1.5.8 → 3.0.4 (required by WSS4J 3.x) - Migrate SoapFunction.java to WSS4J 2.x/3.x API: WSSecHeader(doc) + insertSecurityHeader() + WSSecUsernameToken(secHeader) + build() Application code cleanup: - Remove unused HandlerMappingIntrospector local in ChutneyWebSecurityConfig - Rename Hibernate javax.cache → jakarta.cache in application.yml (Hibernate 7)
- Fix DefaultPrettyPrinter: remove withSeparators override (fields are final in Jackson 3); use jacksonMapperBuilder() builder pattern for mapper initialization - Fix JsonReportWriter: replace ObjectMapper().findAndRegisterModules() with jacksonMapperBuilder().disable(...).build() - Fix JUnit Platform 6: make PostDiscoveryFilter.apply() parameter non-nullable - Fix test files: replace MappingJackson2HttpMessageConverter with JacksonJsonHttpMessageConverter; fix findAndRegisterModules() usages - Fix EmbeddedKafkaZKBroker: replaced by EmbeddedKafkaKraftBroker in Spring Kafka 4 - Fix TextNode: renamed to StringNode in Jackson 3 - Fix ObjectNode.elements(): renamed to values() in Jackson 3 (returns Collection) - Fix HttpHeaders: no longer implements Map in Spring 7, use asMultiValueMap() - Fix HttpEntity(null): disambiguate null constructor call with HttpEntity.EMPTY - Update example module Kotlin version from 1.9.25 to 2.2.0
Jackson 3 with ImmutablesJacksonMixins now produces nested JSON:
{ "metadata": { "id", "title", ... } } — matching the UI expectation.
- Add TypeScript DTO interfaces (TestCaseIndexDto, ScenarioIndexMetadataDto,
ExecutionSummaryDto) to lock the API contract in the frontend
- Fix scenario.service.ts: parse creationDate/updateDate as Date,
use Execution.deserialize for executions, drop ghost version/author reads
- Fix campaign.service.ts: wrong constructor argument order (tags was
landing in the updateDate slot, executions in the version slot);
apply same DTO types and date parsing as scenario.service.ts
Issue Number
fixes #
Describe the changes you've made
Spring Boot 4 Migration
Motivation
Spring Boot 3 reached its end of support window.
This PR upgrades the full stack to Spring Boot 4.1.0 (starting from 4.0.6), which pulls in:
tools.jackson)Dependency Changes
spring-boot-starter-parentspring-boot-dependenciescom.fasterxml.jacksontools.jacksonEmbeddedKafkaZKBroker(ZooKeeper)EmbeddedKafkaKraftBroker(KRaft)spring-boot-starter-aopspring-boot-starter-aspectjspring-boot-starter-test(monolith)webmvc-test,jdbc-test,data-jpa-test,data-ldap-testpostgresql,junit-jupitertestcontainers-postgresql,testcontainers-junit-jupiterJackson 2 → Jackson 3
API Changes
com.fasterxml.jackson.databind.*totools.jackson.databind.*new ObjectMapper()→JsonMapper.builder()...build()findAndRegisterModules()→findAndAddModules()setSerializationInclusion()→changeDefaultPropertyInclusion()SerializationFeature.WRITE_DATES_AS_TIMESTAMPS→DateTimeFeature.WRITE_DATES_AS_TIMESTAMPSMappingJackson2HttpMessageConverter→JacksonJsonHttpMessageConverterJsonGenerator.Feature.AUTO_CLOSE_TARGET→StreamWriteFeature.AUTO_CLOSE_TARGETStdSerializer/JsonDeserializer→ValueDeserializerSerializerProvider→SerializationContextgen.writeStringField()→gen.writeStringProperty()JsonProcessingException/IOExceptioncatch blocks →JacksonExceptioncom.fasterxml.jackson.databind.Module→tools.jackson.databind.JacksonModuleUnchanged
Jackson 3 keeps annotation packages unchanged —
@JsonProperty,@JsonCreator,@JsonIgnore, etc. remain undercom.fasterxml.jackson.annotation.*.Immutables Annotation Inheritance
Jackson 3 no longer inherits annotations through interfaces.
Affected DTOs include:
ExecutionSummaryDtoGwtTestCaseDtoTestCaseIndexDtoDataSetDtoFix applied:
@JsonCreatorstatic factory methods directly on DTO interfaces.ImmutablesJacksonMixinsinWebConfigurationandServerConfiguration.ImmutablesDtoSerializationTestvalidates round-trip serialization/deserialization for all affected DTOs.Spring Security 7
Removed
ChannelSecurityConfigurerrequiresChannel()is no longer available.Replacement:
TomcatHttpsRedirectConfig, activated via thehttps-redirectprofile.Package Changes
OAuth2ResourceServerPropertiesmoved toorg.springframework.boot.security.oauth2.server.resource.autoconfigure.Autoconfiguration Exclusions
@SpringBootApplication(exclude = ...)became@SpringBootApplication(excludeName = ...)because several autoconfiguration classes moved packages.Spring Boot 4 API Changes
Servlet Factory
AbstractServletWebServerFactory→ConfigurableServletWebServerFactoryDataSourceProperties
Moved from
org.springframework.boot.autoconfigure.jdbctoorg.springframework.boot.jdbc.autoconfigure.Prometheus
The Prometheus actuator endpoint is now exposed by default. Integration test updated:
NOT_FOUND→OK.Kafka: ZooKeeper → KRaft
Spring Kafka 4 removed
EmbeddedKafkaZKBrokerand replaced it withEmbeddedKafkaKraftBroker.Impact: KRaft brokers use dynamic ports.
KafkaBrokerStartActionnow explicitly exposesbootstrapServersas an output so scenarios can wire broker addresses correctly.Lucene and Logging
Lucene
OnDiskIndexConfignow treatsCorruptIndexExceptionandIndexFormatTooOldExceptionas recoverable failures. The directory is properly closed before index recreation.Logging
Replaced Undertow loggers (
io.undertow,org.xnio) with Tomcat logger (org.apache.catalina).Bug Fixes Identified During Migration
HTTP Connect Timeout Restored
Component:
HttpClientFactoryDuring the Apache HttpClient 5 migration only socket read timeouts were preserved. Connect timeout was reintroduced:
TCP connection attempts now fail correctly on timeout; all HTTP actions honor connection timeouts again.
Scheduling Campaign Backward Compatibility
Component:
SchedulingCampaignsDtoDeserializerLegacy Jackson 2 persisted
LocalDateTimevalues as arrays:Without a fix, existing persisted files would fail to deserialize.
Solution: Use
treeToValue(...)with a static mapper. Jackson 3'sLocalDateTimeDeserializernow accepts both the legacy array format and ISO-8601 strings ("2020-02-04T07:10:00").KafkaBrokerStopAction Failure Propagation
Previous behavior:
broker.destroy()exceptions were swallowed and the action always returnedok().New behavior:
ko()is returned when broker shutdown fails.HTTPS Enforcement Alignment
Component:
NoAuthSecurityConfigPreviously
NoAuthSecurityConfigstill enforcedrequiresInsecure()whileChutneyWebSecurityConfigno longer did. This inconsistency has been removed. HTTPS redirection is now handled exclusively byTomcatHttpsRedirectConfigunder thehttps-redirectprofile.String Controller Responses
Component:
WebConfigurationJackson 3 JSON-encodes
Stringreturn values ("1") instead of writing them as plain text (1), breaking integrations relying on Spring Boot 3 behavior (curl, Jenkins, scripts).Fix:
application/jsonsupport toStringHttpMessageConverter.extendMessageConverters(...).plainTextStringConverter()helper is exposed onWebConfigurationfor standalone MockMvc test setups that bypass the Spring context.Bare-string endpoints preserve pre-migration output.
Removal of
FAIL_ON_NULL_FOR_PRIMITIVESOverrideComponent:
WebConfigurationThe migration initially retained
FAIL_ON_NULL_FOR_PRIMITIVES = false, which silently converted{"count": null}into0orfalse. The override has been removed to restore strict validation semantics.JiraTargetConfigurationDto Restoration
@JsonCreatormoved from a no-arg constructor to an all-args constructor with explicit@JsonPropertyannotations on parameters. Default behavior for missing proxy fields remains unchanged throughObjects.requireNonNullElse(...).Narrowed Exception Handling
Component:
ScenarioExecutionReportEntitycatch (Exception e)→catch (JacksonException e)to avoid masking unrelated runtime failures.Non-Migration Change
Scenario Index API Enrichment
TestCaseIndexDtonow includesauthorandversion. These fields are exposed through the scenario index API and consumed by the Angular UI.Post-Initial-Migration Bumps
Spring Boot 4.0.6 → 4.1.0
Upgraded after the initial migration settled to pick up Spring Boot 4.1.0 fixes and improvements.
Additional dependency updates in the same pass:
IntelliJ Plugin: Kotlin 2.4.0
The
idea-pluginGradle build was updated separately (it uses its own toolchain):kotlinversion inlibs.versions.toml: 2.3.x → 2.4.0JsonTraversal.ktadapted for Kotlin 2.4 API changesDescribe if there is any unusual behaviour of your code
Additional context
Test plan
Checklist