This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 9f4f1d4f17 FINERACT-2094: Update to Java 21
9f4f1d4f17 is described below
commit 9f4f1d4f177888ff8ff06775731fdfb817e5cd10
Author: Victor Romero <[email protected]>
AuthorDate: Tue Apr 15 01:37:10 2025 -0600
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 [email protected]/java.lang.reflect.Method.invoke(Method.java:580)
at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
at [email protected]/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 ++--
.../workflows/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 +-
.../domain/AbstractAuditableWithUTCDateTimeCustom.java | 8 ++++----
.../core/domain/AbstractPersistableCustom.java | 4 ++--
.../core/serialization/GoogleGsonSerializerHelper.java | 2 +-
.../core/serialization/JsonParserHelper.java | 2 +-
.../domain/BasicPasswordEncodablePlatformUser.java | 4 ++--
fineract-provider/build.gradle | 2 +-
.../bulkimport/importhandler/helper/DateSerializer.java | 2 +-
.../portfolio/loanaccount/service/LoanAssemblerImpl.java | 4 ++--
.../external/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 7b45bdc6b5..f8625dc7fc 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 5f2b10894f..c342e2248c 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 5af33dc148..8591cd85a8 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 6e8890e417..6e3f034486 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 5a79d65345..d792127f09 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 b5b70003f6..bfd2638624 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 0e8a5f14e1..3ac9695c6f 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 169d2e7552..f577565856 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 d13f4f02b9..75c67aa007 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 5624986643..aa4a8a15dc 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 3c69261916..d24665edd7 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 be390601ed..9309d00560 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 085a7b4ecb..d6630775c0 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 e047b4d4f1..7a56d6b7fc 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:
<br>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.<br>
-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.)
<br>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 d2c71b738d..5c13996326 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 28b9415f36..15aab0f998 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 6612602bfd..1107fdbf82 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<T extends Serializa
private static final long serialVersionUID = 141481953116476081L;
@Column(name = CREATED_BY_DB_FIELD, updatable = false, nullable = false)
- @Setter(onMethod = @__(@Override))
+ @Setter(onMethod_ = @Override)
private Long createdBy;
@Column(name = CREATED_DATE_DB_FIELD, updatable = false, nullable = false)
- @Setter(onMethod = @__(@Override))
+ @Setter(onMethod_ = @Override)
private OffsetDateTime createdDate;
@Column(name = LAST_MODIFIED_BY_DB_FIELD, nullable = false)
- @Setter(onMethod = @__(@Override))
+ @Setter(onMethod_ = @Override)
private Long lastModifiedBy;
@Column(name = LAST_MODIFIED_DATE_DB_FIELD, nullable = false)
- @Setter(onMethod = @__(@Override))
+ @Setter(onMethod_ = @Override)
private OffsetDateTime lastModifiedDate;
@Override
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java
index 7c0813fdca..ae4744d424 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java
@@ -54,12 +54,12 @@ public abstract class AbstractPersistableCustom<T extends
Serializable> 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 234a0046ee..1d2b9d56f0 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 e0573cd7c0..c48cc0a9b4 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 bddb8141ef..943703ead3 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 755ac5f32e..9150bf963d 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 85f0147c87..bf83256b2e 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<LocalDate> {
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 6d8ff28723..3938f6e785 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 eee2cb04ba..550997db74 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<ExternalEventView> 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<ExternalEventView> 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];