From 9f4f1d4f177888ff8ff06775731fdfb817e5cd10 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Tue, 15 Apr 2025 01:37:10 -0600 Subject: [PATCH] FINERACT-2094: Update to Java 21 modernize locale instantiations (fixes an error found by the modernizer plugin) - use Locale.of() instead of new Locale() use recommended gradle toolchain syntax to specify Java class file format version see https://docs.gradle.org/current/userguide/java_plugin.html#toolchain_and_compatibility mark html5 for later fix (it's the default) use dummy byte arrays to work around mockito exception ``` org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: class java.nio.ByteBuffer. If you're not sure why you're getting this error, please open an issue on GitHub. Java : 21 JVM vendor name : Ubuntu JVM vendor version : 21.0.6+7-Ubuntu-122.04.1 JVM name : OpenJDK 64-Bit Server VM JVM version : 21.0.6+7-Ubuntu-122.04.1 JVM info : mixed mode, sharing OS name : Linux OS version : 5.15.0-136-generic You are seeing this disclaimer because Mockito is configured to create inlined mocks. You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc. Underlying exception : org.mockito.exceptions.base.MockitoException: Unsupported settings with this type 'java.nio.ByteBuffer' at app//org.apache.fineract.infrastructure.event.external.jobs.SendAsynchronousEventsTaskletTest.givenBatchSize2WhenEventSendFailsThenExecutionStops(SendAsynchronousEventsTaskletTest.java:170) at java.base@21.0.6/java.lang.reflect.Method.invoke(Method.java:580) at java.base@21.0.6/java.util.ArrayList.forEach(ArrayList.java:1596) at java.base@21.0.6/java.util.ArrayList.forEach(ArrayList.java:1596) Caused by: org.mockito.exceptions.base.MockitoException: Unsupported settings with this type 'java.nio.ByteBuffer' at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168) at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399) at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190) at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410) ... 4 more ``` see also: https://stackoverflow.com/questions/47046996/java-lang-unsupportedoperationexception-when-mocking-java-nio-bytebuffer-class wrap byte arrays with ByteBuffer fix: ``` /home/adamm/git/apache/fineract/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java:148: error: incompatible types: byte[] cannot be converted to ByteBuffer "anidempotencyKey", "aSchema", "dummy".getBytes()); ^ /home/adamm/git/apache/fineract/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java:170: error: incompatible types: byte[] cannot be converted to ByteBuffer "anidempotencyKey", "aSchema", "dummy".getBytes()); ^ /home/adamm/git/apache/fineract/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java:189: error: incompatible types: byte[] cannot be converted to ByteBuffer "anidempotencyKey", "aSchema", "dummy".getBytes()); ^ /home/adamm/git/apache/fineract/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java:210: error: incompatible types: byte[] cannot be converted to ByteBuffer "anidempotencyKey", "aSchema", "dummy".getBytes()); ``` ...and use StandardCharsets with getBytes --- .github/workflows/build-docker-mariadb.yml | 4 ++-- .github/workflows/build-docker-postgresql.yml | 4 ++-- .github/workflows/build-documentation.yml | 4 ++-- .../build-embeddable-progressive-loan-jar.yml | 4 ++-- .github/workflows/build-mariadb.yml | 4 ++-- .github/workflows/build-mysql.yml | 4 ++-- .github/workflows/build-postgresql.yml | 4 ++-- .github/workflows/build-tests.yml | 4 ++-- .github/workflows/publish-dockerhub.yml | 4 ++-- .github/workflows/smoke-activemq.yml | 4 ++-- .github/workflows/smoke-kafka.yml | 4 ++-- .github/workflows/sonarqube.yml | 4 ++-- .gitpod.yml | 2 ++ README.md | 6 +++--- build.gradle | 16 +++++++--------- custom/docker/build.gradle | 2 +- .../AbstractAuditableWithUTCDateTimeCustom.java | 8 ++++---- .../core/domain/AbstractPersistableCustom.java | 4 ++-- .../GoogleGsonSerializerHelper.java | 2 +- .../core/serialization/JsonParserHelper.java | 2 +- .../BasicPasswordEncodablePlatformUser.java | 4 ++-- fineract-provider/build.gradle | 2 +- .../importhandler/helper/DateSerializer.java | 2 +- .../loanaccount/service/LoanAssemblerImpl.java | 4 ++-- .../jobs/SendAsynchronousEventsTaskletTest.java | 9 +++++---- 25 files changed, 56 insertions(+), 55 deletions(-) diff --git a/.github/workflows/build-docker-mariadb.yml b/.github/workflows/build-docker-mariadb.yml index 7b45bdc6b..f8625dc7f 100644 --- a/.github/workflows/build-docker-mariadb.yml +++ b/.github/workflows/build-docker-mariadb.yml @@ -12,10 +12,10 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/build-docker-postgresql.yml b/.github/workflows/build-docker-postgresql.yml index 5f2b10894..c342e2248 100644 --- a/.github/workflows/build-docker-postgresql.yml +++ b/.github/workflows/build-docker-postgresql.yml @@ -12,10 +12,10 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml index 5af33dc14..8591cd85a 100644 --- a/.github/workflows/build-documentation.yml +++ b/.github/workflows/build-documentation.yml @@ -12,10 +12,10 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/build-embeddable-progressive-loan-jar.yml b/.github/workflows/build-embeddable-progressive-loan-jar.yml index 6e8890e41..6e3f03448 100644 --- a/.github/workflows/build-embeddable-progressive-loan-jar.yml +++ b/.github/workflows/build-embeddable-progressive-loan-jar.yml @@ -10,10 +10,10 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/build-mariadb.yml b/.github/workflows/build-mariadb.yml index 5a79d6534..d792127f0 100644 --- a/.github/workflows/build-mariadb.yml +++ b/.github/workflows/build-mariadb.yml @@ -28,10 +28,10 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle and Validate Wrapper uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/build-mysql.yml b/.github/workflows/build-mysql.yml index b5b70003f..bfd263862 100644 --- a/.github/workflows/build-mysql.yml +++ b/.github/workflows/build-mysql.yml @@ -28,10 +28,10 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle and Validate Wrapper uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/build-postgresql.yml b/.github/workflows/build-postgresql.yml index 0e8a5f14e..3ac9695c6 100644 --- a/.github/workflows/build-postgresql.yml +++ b/.github/workflows/build-postgresql.yml @@ -29,10 +29,10 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle and Validate Wrapper uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/build-tests.yml b/.github/workflows/build-tests.yml index 169d2e755..f57756585 100644 --- a/.github/workflows/build-tests.yml +++ b/.github/workflows/build-tests.yml @@ -12,10 +12,10 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/publish-dockerhub.yml b/.github/workflows/publish-dockerhub.yml index d13f4f02b..75c67aa00 100644 --- a/.github/workflows/publish-dockerhub.yml +++ b/.github/workflows/publish-dockerhub.yml @@ -18,10 +18,10 @@ jobs: with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle diff --git a/.github/workflows/smoke-activemq.yml b/.github/workflows/smoke-activemq.yml index 562498664..aa4a8a15d 100644 --- a/.github/workflows/smoke-activemq.yml +++ b/.github/workflows/smoke-activemq.yml @@ -12,10 +12,10 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/smoke-kafka.yml b/.github/workflows/smoke-kafka.yml index 3c6926191..d24665edd 100644 --- a/.github/workflows/smoke-kafka.yml +++ b/.github/workflows/smoke-kafka.yml @@ -12,10 +12,10 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml index be390601e..9309d0056 100644 --- a/.github/workflows/sonarqube.yml +++ b/.github/workflows/sonarqube.yml @@ -22,10 +22,10 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' - name: Setup Gradle and Validate Wrapper uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/.gitpod.yml b/.gitpod.yml index 085a7b4ec..d6630775c 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -19,6 +19,8 @@ # https://www.gitpod.io # https://www.gitpod.io/docs/41_Config_Gitpod_File/ # https://github.com/gitpod-io/workspace-images/tree/master/mysql +# +# FIXME - dead code? see https://github.com/apache/fineract/pull/4590#issuecomment-2809760331 image: gitpod/workspace-mysql:2022-08-04-13-40-17 ports: diff --git a/README.md b/README.md index e047b4d4f..7a56d6b7f 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ If you are interested in contributing to this project, but perhaps don't quite k REQUIREMENTS ============ -* `Java >= 17` (Azul Zulu JVM is tested by our CI on GitHub Actions) +* `Java >= 21` (Azul Zulu JVM is tested by our CI on GitHub Actions) * MariaDB `11.5.2` You can run the required version of the database server in a container, instead of having to install it, like this: @@ -38,7 +38,7 @@ and stop and destroy it like this:
Beware that this database container database keeps its state inside the container and not on the host filesystem. It is lost when you destroy (rm) this container. This is typically fine for development. See [Caveats: Where to Store Data on the database container documentation](https://hub.docker.com/_/mariadb) re. how to make it persistent instead of ephemeral.
-Tomcat v9 is only required if you wish to deploy the Fineract WAR to a separate external servlet container. Note that you do not require to install Tomcat to develop Fineract, or to run it in production if you use the self-contained JAR, which transparently embeds a servlet container using Spring Boot. (Until FINERACT-730, Tomcat 7/8 were also supported, but now Tomcat 9 is required.) +Tomcat v10 is only required if you wish to deploy the Fineract WAR to a separate external servlet container. Note that you do not require to install Tomcat to develop Fineract, or to run it in production if you use the self-contained JAR, which transparently embeds a servlet container using Spring Boot. (Until FINERACT-730, Tomcat 7/8 were also supported, but now Tomcat 10 is required.)
IMPORTANT: If you use MySQL or MariaDB ============ @@ -137,7 +137,7 @@ FINERACT_SECURITY_2FA_ENABLED=true ============ 1. Clone the repository or download and extract the archive file to your local directory. 2. Run `./gradlew :fineract-war:clean :fineract-war:war` to build a traditional WAR file which will be created at `fineract-war/build/libs` directory. -3. Deploy this WAR to your Tomcat v9 Servlet Container. +3. Deploy this WAR to your Tomcat v10 Servlet Container. We recommend using the JAR instead of the WAR file deployment, because it's much easier. diff --git a/build.gradle b/build.gradle index d2c71b738..5c1399632 100644 --- a/build.gradle +++ b/build.gradle @@ -355,8 +355,10 @@ configure(project.fineractJavaProjects) { apply plugin: 'idea' java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + toolchain { + languageVersion = JavaLanguageVersion.of(21) + vendor = JvmVendorSpec.AZUL + } withSourcesJar() withJavadocJar() } @@ -402,11 +404,6 @@ configure(project.fineractJavaProjects) { group = 'org.apache.fineract' - /* define the valid syntax level for source files */ - // sourceCompatibility = JavaVersion.VERSION_17 - // /* define binary compatibility version */ - // targetCompatibility = JavaVersion.VERSION_17 - /* http://stackoverflow.com/questions/19653311/jpa-repository-works-in-idea-and-production-but-not-in-gradle */ sourceSets.main.output.resourcesDir = sourceSets.main.java.classesDirectory sourceSets.test.output.resourcesDir = sourceSets.test.java.classesDirectory @@ -741,10 +738,11 @@ configure(project.fineractJavaProjects) { tasks.withType(Javadoc) { options.addStringOption('Xdoclint:none', '-quiet') options.encoding = 'UTF-8' + // FIXME - html5 is the default since sometime before Java 17 // Disable strict checking to prevent build failures on invalid javadoc options.addBooleanOption('html5', true) - // Add this if you're using Java 17 records or other modern features - if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { + // Add this if you're using Java 21 records or other modern features + if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) { options.addBooleanOption('html5', true) } // Ignore any errors during javadoc generation diff --git a/custom/docker/build.gradle b/custom/docker/build.gradle index 28b9415f3..15aab0f99 100644 --- a/custom/docker/build.gradle +++ b/custom/docker/build.gradle @@ -24,7 +24,7 @@ apply from: "${rootDir}/buildSrc/src/main/groovy/org.apache.fineract.dependencie jib { from { - image = 'azul/zulu-openjdk-alpine:17' + image = 'azul/zulu-openjdk-alpine:21' platforms { platform { architecture = System.getProperty("os.arch").equals("aarch64")?"arm64":"amd64" diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableWithUTCDateTimeCustom.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableWithUTCDateTimeCustom.java index 6612602bf..1107fdbf8 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableWithUTCDateTimeCustom.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableWithUTCDateTimeCustom.java @@ -53,19 +53,19 @@ public abstract class AbstractAuditableWithUTCDateTimeCustom implemen @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Getter(onMethod = @__(@Override)) + @Getter(onMethod_ = @Override) private T id; @Transient @Setter(value = AccessLevel.NONE) - @Getter(onMethod = @__(@Override)) + @Getter(onMethod_ = @Override) private boolean isNew = true; @PrePersist diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/GoogleGsonSerializerHelper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/GoogleGsonSerializerHelper.java index 234a0046e..1d2b9d56f 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/GoogleGsonSerializerHelper.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/GoogleGsonSerializerHelper.java @@ -105,7 +105,7 @@ public final class GoogleGsonSerializerHelper { public static void registerTypeAdapters(final GsonBuilder builder) { builder.registerTypeAdapter(java.util.Date.class, new DateAdapter()); builder.registerTypeAdapter(LocalDate.class, new LocalDateAdapter()); - // NOTE: was missing, necessary for GSON serialization with JDK 17's restrictive module access + // NOTE: was missing, necessary for GSON serialization with JDK 21's restrictive module access builder.registerTypeAdapter(LocalTime.class, new LocalTimeAdapter()); builder.registerTypeAdapter(ZonedDateTime.class, new JodaDateTimeAdapter()); builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter()); diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java index e0573cd7c..c48cc0a9b 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java @@ -819,7 +819,7 @@ public class JsonParserHelper { dataValidationErrors); } - return new Locale(languageCode.toLowerCase(), courntryCode.toUpperCase(), variantCode); + return Locale.of(languageCode.toLowerCase(), courntryCode.toUpperCase(), variantCode); } private Locale extractLocaleValue(final JsonObject object) { diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/domain/BasicPasswordEncodablePlatformUser.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/domain/BasicPasswordEncodablePlatformUser.java index bddb8141e..943703ead 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/domain/BasicPasswordEncodablePlatformUser.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/domain/BasicPasswordEncodablePlatformUser.java @@ -32,9 +32,9 @@ public class BasicPasswordEncodablePlatformUser implements PlatformUser { @Getter private Long id; - @Getter(onMethod = @__(@Override)) + @Getter(onMethod_ = @Override) private String username; - @Getter(onMethod = @__(@Override)) + @Getter(onMethod_ = @Override) private String password; @Override diff --git a/fineract-provider/build.gradle b/fineract-provider/build.gradle index 755ac5f32..9150bf963 100644 --- a/fineract-provider/build.gradle +++ b/fineract-provider/build.gradle @@ -258,7 +258,7 @@ bootJar { jib { from { - image = 'azul/zulu-openjdk-alpine:17' + image = 'azul/zulu-openjdk-alpine:21' platforms { platform { architecture = System.getProperty("os.arch").equals("aarch64")?"arm64":"amd64" diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/helper/DateSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/helper/DateSerializer.java index 85f0147c8..bf83256b2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/helper/DateSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/helper/DateSerializer.java @@ -46,7 +46,7 @@ public class DateSerializer implements JsonSerializer { public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context) { DateTimeFormatter formatter; if (StringUtils.isNotEmpty(localeCode)) { - formatter = DateTimeFormatter.ofPattern(dateFormat, new Locale(localeCode)); + formatter = DateTimeFormatter.ofPattern(dateFormat, Locale.of(localeCode)); } else { formatter = DateTimeFormatter.ofPattern(dateFormat); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java index 6d8ff2872..3938f6e78 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java @@ -890,7 +890,7 @@ public class LoanAssemblerImpl implements LoanAssembler { loan.setClosedOnDate(withdrawnOn); loan.setClosedBy(currentUser); - final Locale locale = new Locale(command.locale()); + final Locale locale = Locale.of(command.locale()); final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale); actualChanges.put(Loan.PARAM_STATUS, LoanEnumerations.status(loan.getStatus())); @@ -912,7 +912,7 @@ public class LoanAssemblerImpl implements LoanAssembler { loan.setClosedOnDate(rejectedOn); loan.setClosedBy(currentUser); - final Locale locale = new Locale(command.locale()); + final Locale locale = Locale.of(command.locale()); final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale); actualChanges.put(Loan.PARAM_STATUS, LoanEnumerations.status(loan.getStatus())); diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java index eee2cb04b..550997db7 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTaskletTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.ZoneId; import java.util.ArrayList; @@ -145,7 +146,7 @@ class SendAsynchronousEventsTaskletTest { createExternalEventView("aType", "aCategory", "aSchema", new byte[0], "aIdempotencyKey", 1L)); // Dummy Message MessageV1 dummyMessage = new MessageV1(1L, "aSource", "aType", "nocategory", "aCreateDate", "aBusinessDate", "aTenantId", - "anidempotencyKey", "aSchema", Mockito.mock(ByteBuffer.class)); + "anidempotencyKey", "aSchema", ByteBuffer.wrap("dummy".getBytes(StandardCharsets.UTF_8))); when(repository.findByStatusOrderByBusinessDateAscIdAsc(Mockito.any(), Mockito.any())).thenReturn(events); when(messageFactory.createMessage(Mockito.any())).thenReturn(dummyMessage); @@ -167,7 +168,7 @@ class SendAsynchronousEventsTaskletTest { createExternalEventView("aType", "aCategory", "aSchema", new byte[0], "aIdempotencyKey", 1L), createExternalEventView("aType", "aCategory", "aSchema", new byte[0], "aIdempotencyKey", 1L)); MessageV1 dummyMessage = new MessageV1(1L, "aSource", "aType", "nocategory", "aCreateDate", "aBusinessDate", "aTenantId", - "anidempotencyKey", "aSchema", Mockito.mock(ByteBuffer.class)); + "anidempotencyKey", "aSchema", ByteBuffer.wrap("dummy".getBytes(StandardCharsets.UTF_8))); when(repository.findByStatusOrderByBusinessDateAscIdAsc(Mockito.any(), Mockito.any())).thenReturn(events); when(messageFactory.createMessage(Mockito.any())).thenReturn(dummyMessage); when(byteBufferConverter.convert(Mockito.any(ByteBuffer.class))).thenReturn(new byte[0]); @@ -186,7 +187,7 @@ class SendAsynchronousEventsTaskletTest { List events = Arrays .asList(createExternalEventView("aType", "aCategory", "aSchema", new byte[0], "aIdempotencyKey", 1L)); MessageV1 dummyMessage = new MessageV1(1L, "aSource", "aType", "nocategory", "aCreateDate", "aBusinessDate", "aTenantId", - "anidempotencyKey", "aSchema", Mockito.mock(ByteBuffer.class)); + "anidempotencyKey", "aSchema", ByteBuffer.wrap("dummy".getBytes(StandardCharsets.UTF_8))); when(repository.findByStatusOrderByBusinessDateAscIdAsc(Mockito.any(), Mockito.any())).thenReturn(events); when(messageFactory.createMessage(Mockito.any())).thenReturn(dummyMessage); when(byteBufferConverter.convert(Mockito.any(ByteBuffer.class))).thenReturn(new byte[0]); @@ -207,7 +208,7 @@ class SendAsynchronousEventsTaskletTest { List events = Arrays .asList(createExternalEventView("aType", "aCategory", "aSchema", new byte[0], "aIdempotencyKey", null)); MessageV1 dummyMessage = new MessageV1(1L, "aSource", "aType", "nocategory", "aCreateDate", "aBusinessDate", "aTenantId", - "anidempotencyKey", "aSchema", Mockito.mock(ByteBuffer.class)); + "anidempotencyKey", "aSchema", ByteBuffer.wrap("dummy".getBytes(StandardCharsets.UTF_8))); when(repository.findByStatusOrderByBusinessDateAscIdAsc(Mockito.any(), Mockito.any())).thenReturn(events); when(messageFactory.createMessage(Mockito.any())).thenReturn(dummyMessage); byte[] byteMsg = new byte[0];