fix: migrate to http4k 6 (Java 21 / Kotlin 2.4) + tooling & dependency upgrades (#95)#96
Open
juherr wants to merge 16 commits into
Open
fix: migrate to http4k 6 (Java 21 / Kotlin 2.4) + tooling & dependency upgrades (#95)#96juherr wants to merge 16 commits into
juherr wants to merge 16 commits into
Conversation
http4k 6.x removed org.http4k.routing.WsRouter, causing a runtime NoClassDefFoundError for applications running on http4k 6. Recompile the toolkit against http4k 6.53.0.0. http4k 6 requires Java 21 and is built with Kotlin 2.4, so: - bump JVM target 17 -> 21 (build + CI) - bump Kotlin 1.9.22 -> 2.4.0, migrate kotlinOptions -> compilerOptions DSL - decouple buildSrc from the Kotlin plugin (it only needs to expose it to subprojects; keeping it on buildSrc's own classpath conflicts with the kotlin-dsl embedded language version) http4k 6 API changes: - ocpp-transport-soap: http4k-contract -> http4k-api-openapi - OcppWampServerApp: routing.ws.bind -> routing.websocket.bind - UndertowWebSocketCallBack: removed WsMessage(Body) constructor - CSMS: routes()/websockets() now throw on empty input -> pass null Also: KGP 2.x no longer makes testFixturesImplementation extend implementation, so kotlinx-datetime is declared explicitly in generic-api. BREAKING CHANGE: the toolkit now requires Java 21 and http4k 6.x.
Refresh the non-http4k dependencies now that the toolkit builds on Java 21 / Kotlin 2.4: - jackson 2.16.1 -> 2.19.4 - kotlinx-coroutines 1.6.4 -> 1.10.2 - kotlinx-datetime 0.4.0 -> 0.4.1 (also reconcile the hardcoded 0.3.2 in coreProject and generic-api testFixtures onto the managed version) - undertow 2.3.12 -> 2.3.24.Final - junit-jupiter 5.9.1 -> 5.11.4 - mockk 1.14.0 -> 1.14.11 - logback-classic 1.4.4 -> 1.5.18 - slf4j-api 2.0.3 -> 2.0.18 - commons-lang3 3.12.0 -> 3.18.0 - mapstruct 1.5.3 -> 1.6.3 - json-schema-validator 1.0.73 -> 1.0.88 - kotlin-logging 3.0.4 -> 3.0.5 - mockito 4.8.1 -> 4.11.0, mockito-kotlin 4.0.0 -> 4.1.0 - strikt 0.34.1 -> 0.35.1 Deliberately kept within the current major for deps whose next major needs a code migration: json-schema-validator (2.x/3.x API rewrite), mockito (5.x drops mockito-inline), kotlinx-datetime (0.6+/0.7 removes kotlinx.datetime.Instant), junit-jupiter (5.14 needs a newer platform launcher than Gradle bundles; 6.x is a new major), kotlin-logging 4.x.
- bump Gradle wrapper 8.12 -> 8.14.5 (the Kotlin 2.4 plugin warns that Gradle < 8.14.4 is deprecated and unsupported from Kotlin 2.5) - raise Kotlin language/api version 2.0 -> 2.2 (2.0 is deprecated by the 2.4 compiler)
Adaptations required by the Gradle 9 major:
- migrate the build-scan plugin com.gradle.enterprise 3.13.1 ->
com.gradle.develocity 4.4.3 (gradleEnterprise{} -> develocity{},
termsOfService* -> termsOfUse*); the old plugin called the removed
Provider.forUseAtConfigurationTime() and broke at configuration time
- bump refreshVersions 0.51.0 -> 0.60.6 (Gradle 9 compatible)
- declare junit-platform-launcher explicitly on the test runtime classpath
(Gradle 9 no longer adds it implicitly)
Straightforward version bumps to the latest stable, no source changes: - jackson 2.19.4 -> 2.22.0 - kotlinx-coroutines 1.10.2 -> 1.11.0 - commons-lang3 3.18.0 -> 3.20.0 - logback-classic 1.5.18 -> 1.5.35
undertow-servlet was discontinued after 2.3.x (no 2.4.x release) and was not used anywhere in the code (only undertow-core APIs are referenced), so drop the undertow-servlet dependency and bump undertow-core to 2.4.1.Final.
Adaptations for the json-schema-validator 1.0.88 -> 1.5.9 bump: - since 1.5.x validation messages are localized with the default JVM locale; pin OcppJsonValidator to Locale.ENGLISH so OCPP error details stay deterministic regardless of the server locale - the order of reported validation messages changed (additionalProperties now before required); update the affected assertion indices in Ocpp20JsonParserTest Kept on the 1.x line: 2.x/3.x is a ground-up API rewrite (Schema / SchemaRegistry / Error replace JsonSchema / JsonSchemaFactory / ValidationMessage / ValidatorTypeCode) that changes the OCPP validation error model and needs a dedicated migration.
mockito-kotlin 4.1.0 -> 6.3.0, which pulls mockito-core 5.x transitively. The mockito-inline artifact was discontinued after 5.2.0 (the inline mock maker is the default in mockito 5), so drop the mockito-inline test dependency and the now-unused version.mockito key. The toolkit test only uses Mockito.spy + org.mockito.kotlin.*, both still provided.
junit-jupiter 5.11.4 -> 6.1.0 (JUnit 6 unified the jupiter and platform versions), and bump the explicit junit-platform-launcher to the matching 6.1.0. No test API changes were needed. JUnit 6 requires Java 17+, already satisfied by the Java 21 toolchain.
Pin actions/setup-java, actions/checkout and gradle/gradle-build-action to full commit SHAs (with the version in a trailing comment) instead of floating major tags, for supply-chain safety.
Address review feedback: keep all versions in versions.properties / under
refreshVersions control rather than hardcoding them in build scripts.
- root build.gradle.kts: drop the explicit kotlin("jvm") version "2.4.0";
refreshVersions resolves it from version.kotlin
- coreProject: kotlinx-datetime and junit-platform-launcher now use the ":_"
placeholder (junit-platform-launcher version moved to versions.properties)
- generic-api: same ":_" for the testFixtures kotlinx-datetime dependency
d33f655 to
b1e4957
Compare
WebsocketTest.receiveMessageClass pushed a server-initiated CALL after a fixed Thread.sleep(100), which is racy on slow CI (NoConnectionException on GitHub Actions). Retry the send until the connection is registered server-side, up to a 5s timeout.
gradle/gradle-build-action and its 'arguments' parameter are deprecated. Use gradle/actions/setup-gradle (pinned to its commit SHA) and run the build through a plain './gradlew build' step.
http4k 6 moved PolyHandler from org.http4k.server to org.http4k.core and deprecated the old alias/constructor. Import from the new package.
Silence the Jackson deprecation warnings surfaced by the jackson 2.22 bump: - drop the redundant setSerializationInclusion(...) calls: each is followed by an equivalent setDefaultPropertyInclusion(...) that already sets the same default inclusion - drop the redundant enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_*) calls in the 1.5/1.6 SOAP mappers (the base OcppSoapMapper already enables them and they are inherited via the copy constructor) - keep (and @Suppress) the base OcppSoapMapper enable(MapperFeature) calls: the builder-based alternatives do not reproduce the XmlMapper(factory, CustomXmlModule) construction this mapper depends on No behavior change; the SOAP 1.5/1.6 and JSON parser test suites still pass.
…ature) Reference jackson-databind#3782: the builder/rebuild() replacement is only available on JsonMapper in 2.x (XmlMapper has no rebuild(), and a fully functioning rebuild() lands in Jackson 3.0), XmlMapper.builder() does not reproduce the XmlMapper(factory, CustomXmlModule) construction, and the case-insensitive features are required. Documents that a clean fix needs the Jackson 3 migration (same prerequisite as json-schema-validator 3.x).
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



What & why
Fixes #95. Applications that moved to http4k 6.x crash at runtime with
NoClassDefFoundError: org/http4k/routing/WsRouterbecause the toolkit wascompiled against http4k 5.x (binary incompatibility). This PR recompiles the
toolkit against http4k 6.53.0.0 and, as a consequence, brings the build
chain forward (http4k 6 requires Java 21 and ships Kotlin 2.4 bytecode).
Consumers on Java 17 / http4k 5 must stay on the current released line.
Core migration (http4k 5 → 6)
ocpp-wamp: WS routing importrouting.ws.bind→routing.websocket.bind;WsMessage(Body(...))→WsMessage(...)(constructor removed in v6).toolkitCSMS:routes()/websockets()now throw on empty input → passnullfor the absent protocol side.ocpp-transport-soap:http4k-contract→http4k-api-openapi(artifactrenamed in v6;
org.http4k.contract.*API unchanged).Undertow.kt, subprotocol handshake) compilesunchanged on v6 —
PolyServerConfig/Http4kUndertowHttpHandler/Http4kWebSocketCallback/RoutingWsHandlerare intact.Build chain & tooling
kotlinOptions→compilerOptionsDSL;decouple
buildSrcfrom the Kotlin plugin (it only exposes it to subprojects).com.gradle.enterprise→com.gradle.develocity4.4.3, bump refreshVersionsto 0.60.6, and declare
junit-platform-launcherexplicitly (Gradle 9 nolonger adds it implicitly).
testFixturesImplementationno longer extendsimplementation(declare kotlinx-datetime explicitly in
generic-api).Dependency upgrades (to latest stable)
jackson 2.22.0 · kotlinx-coroutines 1.11.0 · commons-lang3 3.20.0 ·
logback 1.5.35 · undertow 2.4.1.Final (drop unused
undertow-servlet,discontinued in 2.4.x) · json-schema-validator 1.5.9 · mockito-kotlin 6.3.0
(mockito 5.x; drop
mockito-inline) · JUnit 6.1.0.(kotlin-logging, mapstruct and slf4j only have pre-releases beyond their
current stable, so they were left as-is.)
🚧 Needs an architecture decision (intentionally NOT upgraded here)
Two libraries cannot be moved to their latest release as a routine bump —
each is a major migration with consumer-visible behavioural impact, so
they're kept at the latest compatible version and flagged for a deliberate
decision:
json-schema-validator — kept at 1.5.9 (latest 1.x)
tools.jackson.*), incompatible with thetoolkit's pervasive Jackson 2.x (
com.fasterxml.jackson). Adopting it meanseither a full Jackson 2 → 3 migration of the whole toolkit, or a
conversion bridge (double-parsing).
API (
Schema/SchemaRegistry/Error), which dropsValidatorTypeCodeand numeric error codes. The OCPP error
codefield would change fromnumeric (
1001/1028) to JSON Schema keywords (additionalProperties/required) — a change to the error responses we send.and accept (or compat-map) the error-model change.
kotlinx-datetime — kept at 0.4.1
kotlinx.datetime.Instantin favour ofkotlin.time.Instant(~117 files use it), make thetoJavaInstant/toKotlinInstantinterop helpersinternal, and makeInstant.parsestricter — it rejects timestamps without seconds (
2023-10-06T12:33Z),an OCPP interoperability concern.
kotlin.time.Instant, or use the0.x-compatflavour and decide whether to keep lenient timestamp parsing.Verification
./gradlew buildis green on JDK 21 (full suite, ~565 tests), including theWAMP WebSocket handshake (
WampIntegrationTest) and the CSMS assembly(
IntegrationTestCSApi).🤖 Generated with Claude Code