From 1972fdcefe2747f0c4405b06928154c1d2a755fa Mon Sep 17 00:00:00 2001 From: stephane brossier Date: Tue, 17 Feb 2026 15:49:54 -0800 Subject: [PATCH] Modify java generator to not use joda time anymore. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary of Joda Removal Changes for Generator Update 1. Type Mapping Changes (the core generator change) The generator needs to update its type mappings for date/time types: Swagger Type Old Java Type New Java Type date-time org.joda.time.DateTime java.time.ZonedDateTime date org.joda.time.LocalDate java.time.LocalDate This is a global find-and-replace in the generator's type map. Every place the generator emits DateTime (from Joda), it should emit ZonedDateTime instead. LocalDate keeps the same class name but moves from org.joda.time to java.time. 2. Import Changes Old Import New Import import org.joda.time.DateTime; import java.time.ZonedDateTime; import org.joda.time.LocalDate; import java.time.LocalDate; 3. Affected Generated Code Locations Model classes (model/gen/) — 16 files affected. Every field, constructor parameter, getter, and setter that used DateTime now uses ZonedDateTime. Files using only LocalDate (Invoice, InvoiceDryRun) just had the import change. No behavioral/structural changes — it's purely a type substitution. API classes (api/gen/) — 6 files affected. Method parameter types changed from DateTime → ZonedDateTime and imports changed from org.joda.time.* → java.time.*. The method bodies (query parameter serialization via String.valueOf(...)) are unchanged. 4. Non-Generated (Manual) Changes — FYI only These are not generator concerns but relevant context: pom.xml: Replaced jackson-datatype-joda dependency with jackson-datatype-jsr310. Removed the joda-time dependency entirely. KillBillHttpClient.java: Changed JodaModule → JavaTimeModule, added mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS). CatalogVersions.java and DateTimes.java: Changed ArrayList → ArrayList (these are hand-maintained wrapper types). 5. Generator Change Checklist In the type mapping configuration, change the mapping for the date-time swagger format from org.joda.time.DateTime to java.time.ZonedDateTime In the type mapping configuration, change the mapping for the date swagger format from org.joda.time.LocalDate to java.time.LocalDate In the import mapping configuration, replace org.joda.time.DateTime → java.time.ZonedDateTime and org.joda.time.LocalDate → java.time.LocalDate No template/mustache changes needed — the transformation is purely at the type/import mapping level --- .../languages/KillbillJavaGenerator.java | 32 ++++++++++++------- src/main/resources/killbill-java/api.mustache | 2 ++ .../killbill-java/api_query.mustache | 5 +++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/killbill/billing/codegen/languages/KillbillJavaGenerator.java b/src/main/java/org/killbill/billing/codegen/languages/KillbillJavaGenerator.java index 26ab24f..6ae1b27 100644 --- a/src/main/java/org/killbill/billing/codegen/languages/KillbillJavaGenerator.java +++ b/src/main/java/org/killbill/billing/codegen/languages/KillbillJavaGenerator.java @@ -117,6 +117,8 @@ public void processOpts() { typeMapping.put("array", "List"); typeMapping.put("map", "Map"); + typeMapping.put("date", "LocalDate"); + typeMapping.put("DateTime", "ZonedDateTime"); typeMapping.put("file", "java.io.File"); @@ -128,8 +130,8 @@ public void processOpts() { importMapping.put("List", "java.util.List"); importMapping.put("LinkedList", "java.util.LinkedList"); importMapping.put("ArrayList", "java.util.ArrayList"); - importMapping.put("DateTime", "org.joda.time.DateTime"); - importMapping.put("LocalDate", "org.joda.time.LocalDate"); + importMapping.put("ZonedDateTime", "java.time.ZonedDateTime"); + importMapping.put("LocalDate", "java.time.LocalDate"); importMapping.put("BigDecimal", "java.math.BigDecimal"); importMapping.put("HashMap", "java.util.HashMap"); importMapping.put("Map", "java.util.Map"); @@ -217,17 +219,18 @@ public Map postProcessOperations(Map objs) { addAllImportsIfRequired(ext, imports); convertToExtendedCodegenParam(ext, imports); if (shouldAddDateTimeMethod(op)) { - addImportIfRequired(imports, "org.joda.time.DateTime"); - addImportIfRequired(imports, "org.joda.time.LocalDate"); + addImportIfRequired(imports, "java.time.ZonedDateTime"); + addImportIfRequired(imports, "java.time.LocalDate"); final ExtendedCodegenOperation ext2 = new ExtendedCodegenOperation(op); addAllImportsIfRequired(ext2, imports); - List allParams = ext2.allParams; - for (CodegenParameter parameter : allParams) { - if (isDateParameter(parameter)) { - parameter.dataFormat = "date-time"; - parameter.isDate = false; - parameter.isDateTime = true; - parameter.dataType = "DateTime"; + for (List paramList : Arrays.asList(ext2.allParams, ext2.queryParams)) { + for (CodegenParameter parameter : paramList) { + if (isDateParameter(parameter)) { + parameter.dataFormat = "date-time"; + parameter.isDate = false; + parameter.isDateTime = true; + parameter.dataType = "ZonedDateTime"; + } } } convertToExtendedCodegenParam(ext2, imports); @@ -444,7 +447,12 @@ private ExtendedCodegenOperation(CodegenOperation o) { returnContainer.equals("array") && this.returnBaseType != null; if (isReturnModelRefContainer) { - this.returnType = String.format("%ss", this.returnBaseType); + // ZonedDateTime wrapper class is still called DateTimes (hand-maintained) + if ("ZonedDateTime".equals(this.returnBaseType)) { + this.returnType = "DateTimes"; + } else { + this.returnType = String.format("%ss", this.returnBaseType); + } } this.isStream = produces != null && !produces.isEmpty() && produces.get(0).get("mediaType").equals("application/octet-stream"); this.hasNonRequiredDefaultQueryParams = this.queryParams diff --git a/src/main/resources/killbill-java/api.mustache b/src/main/resources/killbill-java/api.mustache index f843ad4..53c9c90 100644 --- a/src/main/resources/killbill-java/api.mustache +++ b/src/main/resources/killbill-java/api.mustache @@ -7,6 +7,8 @@ import java.util.Objects; {{#imports}}import {{import}}; {{/imports}} +import java.time.format.DateTimeFormatter; + import org.killbill.billing.client.Converter; import org.killbill.billing.client.KillBillClientException; import org.killbill.billing.client.KillBillHttpClient; diff --git a/src/main/resources/killbill-java/api_query.mustache b/src/main/resources/killbill-java/api_query.mustache index fc7b471..2bb7e8b 100644 --- a/src/main/resources/killbill-java/api_query.mustache +++ b/src/main/resources/killbill-java/api_query.mustache @@ -29,7 +29,12 @@ {{/isMapContainer}} {{^isMapContainer}} if ({{paramName}} != null) { + {{#isDateTime}} + queryParams.put("{{baseName}}", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format({{paramName}})); + {{/isDateTime}} + {{^isDateTime}} queryParams.put("{{baseName}}", String.valueOf({{paramName}})); + {{/isDateTime}} } {{/isMapContainer}} {{/isListContainer}}