From b2a9d3828f6abfa1bfff6348ba6d197bd9fd4c36 Mon Sep 17 00:00:00 2001 From: Ashish Vijaywargiya Date: Wed, 15 Jul 2026 21:52:06 +0530 Subject: [PATCH 1/4] 1. Added sourceCompatibility/targetCompatibility and javadoc source to Java 21 2. Add --add-opens/--enable-native-access JVM args for Tomcat 10.1, Groovy 5, JMockit and Mockito 3. Replace deprecated Locale/Thread APIs (new Locale(...) -> Locale.of(...), Thread.getId() -> threadId()) across framework and application modules 4. Switch log4j-slf4j-impl dependency to the slf4j2 variant 5. Raise Gradle daemon heap settings in gradle.properties --- .../jobshopmgt/ProductionRunContent.groovy | 2 +- .../workeffort/WorkEffortServices.java | 2 +- build.gradle | 25 ++++++++++++++----- dependencies.gradle | 2 +- .../org/apache/ofbiz/base/util/UtilCodec.java | 10 ++++---- .../org/apache/ofbiz/base/util/UtilMisc.java | 2 +- .../apache/ofbiz/base/util/UtilNumber.java | 4 +-- .../ofbiz/base/util/UtilProperties.java | 2 +- .../org/apache/ofbiz/base/util/UtilXml.java | 3 ++- .../collection/FlexibleMapAccessorTest.groovy | 2 +- .../string/FlexibleStringExpanderTests.groovy | 4 +-- .../ofbiz/base/util/UtilCodecTests.java | 6 ++--- .../ofbiz/base/util/UtilPropertiesTests.java | 2 +- .../org/apache/ofbiz/common/CommonEvents.java | 2 +- .../ofbiz/entity/jdbc/SQLProcessor.java | 2 +- .../entity/transaction/TransactionUtil.java | 8 +++--- .../ofbiz/entity/util/EntityDataLoader.java | 12 ++++----- .../data/EntityDataLoadContainer.java | 8 +++--- .../org/apache/ofbiz/base/start/Config.java | 6 ++--- .../ofbiz/testtools/EntityXmlAssertTest.java | 1 + .../ofbiz/webapp/control/JWTManager.java | 4 +-- .../webapp/ftl/OfbizCurrencyTransform.java | 2 +- .../webapp/ftl/OfbizNumberTransform.java | 2 +- .../ofbiz/webtools/WebToolsServices.java | 4 +-- .../RenderableFtlFormElementsBuilderTest.java | 2 +- gradle.properties | 6 ++--- 26 files changed, 70 insertions(+), 55 deletions(-) diff --git a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy index 4be5a7661c6..52164a1ee1a 100644 --- a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy +++ b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy @@ -37,7 +37,7 @@ if (context.delivProductId && (parameters.partyId || parameters.contentLocale)) Locale contentLocale = null if (parameters.contentLocale) { - contentLocale = new Locale(parameters.contentLocale) + contentLocale = Locale.of(parameters.contentLocale) } delivProductContentsForLocaleAndUser = [] delivProductContents.each { delivProductContent -> diff --git a/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java b/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java index 5fff1f73070..485e7e7f5ee 100644 --- a/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java +++ b/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java @@ -953,7 +953,7 @@ public static Map processWorkEffortEventReminders(DispatchContex } continue; } - Locale locale = reminder.getString("localeId") == null ? Locale.getDefault() : new Locale(reminder.getString("localeId")); + Locale locale = reminder.getString("localeId") == null ? Locale.getDefault() : Locale.of(reminder.getString("localeId")); TimeZone timeZone = reminder.getString("timeZoneId") == null ? TimeZone.getDefault() : TimeZone.getTimeZone(reminder.getString("timeZoneId")); Map parameters = UtilMisc.toMap("locale", locale, "timeZone", timeZone, "workEffortId", reminder.get("workEffortId")); diff --git a/build.gradle b/build.gradle index 7c0d72f6b2c..77ddacac414 100644 --- a/build.gradle +++ b/build.gradle @@ -120,9 +120,16 @@ application { mainClass = 'org.apache.ofbiz.base.start.Start' applicationDefaultJvmArgs = project.hasProperty('jvmArgs') ? jvmArgs.tokenize() - : ['-Xms128M','-Xmx1024M', + : ['-Xms128M', '-Xmx1024M', '-Djdk.serialFilter=maxarray=100000;maxdepth=20;maxrefs=1000;maxbytes=500000', // OFBIZ-12592 and OFBIZ-12716 - '--add-opens=java.base/java.util=ALL-UNNAMED' // OFBIZ-12726 + // Required for embedded Tomcat 10.1 and libraries (Groovy 5, Spring 6) under Java 17+ strong encapsulation + '--add-opens=java.base/java.lang=ALL-UNNAMED', + '--add-opens=java.base/java.io=ALL-UNNAMED', + '--add-opens=java.base/java.util=ALL-UNNAMED', // OFBIZ-12726 + '--add-opens=java.base/java.util.concurrent=ALL-UNNAMED', + '--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED', + // Allow libraries using the stable Foreign Function & Memory API (Apache SSHD, Tika) + '--enable-native-access=ALL-UNNAMED', ] } @@ -134,13 +141,13 @@ javadoc { title="OFBiz " + getCurrentGitBranch() + " API" failOnError = true options { - source '17' + source '21' encoding 'UTF-8' charSet 'UTF-8' // Those external Javadoc links should correspond to the actual // versions declared in the 'dependencies' block. links( - 'https://docs.oracle.com/en/java/javase/17/docs/api/', + 'https://docs.oracle.com/en/java/javase/21/docs/api/', 'https://tomcat.apache.org/tomcat-10.1-doc/servletapi/', 'http://docs.groovy-lang.org/docs/groovy-4.0.22/html/api', 'https://commons.apache.org/proper/commons-cli/apidocs' @@ -152,8 +159,8 @@ javadoc { } java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } // Java compile options, syntax gradlew -PXlint:none build @@ -163,6 +170,8 @@ tasks.withType(JavaCompile) { options.compilerArgs << '-Xlint:all' // Exclude varargs warnings which are not silenced by @SafeVarargs. options.compilerArgs << '-Xlint:-varargs' + // Exclude this-escape warnings pending proper refactoring of widget/service classes. + options.compilerArgs << '-Xlint:-this-escape' } } @@ -363,6 +372,10 @@ tasks.eclipse.dependsOn(cleanEclipse) test { useJUnitPlatform() jvmArgs "-javaagent:${classpath.find { it.name.contains('jmockit') }.absolutePath}" + // Required for JMockit instrumentation, Mockito, and Spring Test under Java 21 + jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED' + jvmArgs '--add-opens=java.base/java.lang.reflect=ALL-UNNAMED' + jvmArgs '--enable-native-access=ALL-UNNAMED' testLogging { events "passed", "skipped", "failed" } diff --git a/dependencies.gradle b/dependencies.gradle index ab8ef10dbaf..03303d97ae1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -110,7 +110,7 @@ dependencies { runtimeOnly 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:2.1' runtimeOnly 'org.apache.logging.log4j:log4j-1.2-api:2.25.4' // for external jars using the old log4j1.2: routes logging to log4j 2 runtimeOnly 'org.apache.logging.log4j:log4j-jul:2.25.4' // for external jars using the java.util.logging: routes logging to log4j 2 - runtimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl:2.25.4' // for external jars using slf4j: routes logging to log4j 2 + runtimeOnly 'org.apache.logging.log4j:log4j-slf4j2-impl:2.25.4' // for external jars using slf4j 2.x: routes logging to log4j 2 runtimeOnly 'org.apache.logging.log4j:log4j-web:2.25.4' //??? runtimeOnly 'org.apache.logging.log4j:log4j-jcl:2.25.4' // need to constrain to version to avoid classpath conflict (ReflectionUtil) diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java index cf07507adf7..099b1f237a5 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java @@ -435,7 +435,7 @@ public static String checkStringForHtmlStrictNone(String valueName, String value Debug.logError("Canonicalization (format consistency, character escaping that is mixed or double, etc) " + "error for attribute named [" + valueName + "], String [" + value + "]: " + e.toString(), MODULE); String issueMsg = null; - if (locale.equals(new Locale("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task issueMsg = "In field [" + valueName + "] found character escaping (mixed or double) " + "that is not allowed or other format consistency error: "; } else { @@ -448,7 +448,7 @@ public static String checkStringForHtmlStrictNone(String valueName, String value // check for "<", ">" if (value.indexOf("<") >= 0 || value.indexOf(">") >= 0) { String issueMsg = null; - if (locale.equals(new Locale("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task issueMsg = "In field [" + valueName + "] less-than (<) and greater-than (>) symbols are not allowed."; } else { issueMsg = UtilProperties.getMessage("SecurityUiLabels", "PolicyNoneLess-thanGreater-than", @@ -463,7 +463,7 @@ public static String checkStringForHtmlStrictNone(String valueName, String value if (JS_EVENT_LIST.stream().anyMatch(s -> s.toLowerCase(Locale.ROOT).contains(onEventLower)) || value.contains("seekSegmentTime")) { String issueMsg = null; - if (locale.equals(new Locale("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task issueMsg = "In field [" + valueName + "] Javascript events are not allowed."; } else { issueMsg = UtilProperties.getMessage("SecurityUiLabels", "PolicyNoneJsEvents", @@ -501,7 +501,7 @@ public static String checkStringForHtmlSafe(String valueName, String value, List PolicyFactory policy = null; try { Class customPolicyClass = null; - if (locale.equals(new Locale("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task customPolicyClass = Class.forName("org.apache.ofbiz.base.html.CustomSafePolicy"); } else { customPolicyClass = Class.forName(UtilProperties.getPropertyValue("owasp", "sanitizer.custom.safe.policy.class")); @@ -566,7 +566,7 @@ public void closeDocument() { // Maybe later we will figure out that some more HTML entities will need to be added to here, see OFBIZ-12691 if (filtered != null && !value.replace("'", "'").replace(""", "\"").replace("@", "@").equals(unescapeEcmaScriptAndHtml4)) { String issueMsg = null; - if (locale.equals(new Locale("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task issueMsg = "In field [" + valueName + "] by our input policy, your input has not been accepted " + "for security reason. Please check and modify accordingly, thanks."; } else { diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java index 30fbcb3bd2c..b0b70fc4596 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java @@ -569,7 +569,7 @@ public static Locale parseLocale(String localeString) { String language = localeString.substring(0, 2); String country = localeString.substring(3, 5); String extension = localeString.substring(6); - locale = new Locale(language, country, extension); + locale = Locale.of(language, country, extension); } else { Debug.logWarning("Do not know what to do with the localeString [" + localeString + "], should be length 2, 5, or greater than 6, " + "returning null", MODULE); diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java index 659a507a227..e62dafe7f08 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java @@ -172,8 +172,8 @@ public final class UtilNumber { static { rbnfRuleSets = new HashMap<>(); rbnfRuleSets.put(Locale.US, RULE_SET_EN_US); - rbnfRuleSets.put(new Locale("th"), RULE_SET_TH_TH); - rbnfRuleSets.put(new Locale("en", "IN"), RULE_SET_EN_IN); + rbnfRuleSets.put(Locale.of("th"), RULE_SET_TH_TH); + rbnfRuleSets.put(Locale.of("en", "IN"), RULE_SET_EN_IN); } private UtilNumber() { } diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java index ce9b63e7423..57a496d2ff7 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java @@ -758,7 +758,7 @@ public static List localeToCandidateList(Locale locale) { int pos = localeString.lastIndexOf("_", localeString.length()); while (pos != -1) { localeString = localeString.substring(0, pos); - localeList.add(new Locale(localeString)); + localeList.add(Locale.of(localeString)); pos = localeString.lastIndexOf("_", localeString.length()); } return localeList; diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilXml.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilXml.java index 8fff8b7727f..1c8777d1150 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilXml.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilXml.java @@ -29,6 +29,7 @@ import java.io.Reader; import java.io.StringWriter; import java.io.Writer; +import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.util.LinkedList; @@ -417,7 +418,7 @@ public static Document readXmlDocument(URL url, boolean validate, boolean withPo innerUrlStr = innerUrlStr.substring(0, bangIdx); } try { - urlHost = new URL(innerUrlStr).getHost(); + urlHost = URI.create(innerUrlStr).toURL().getHost(); } catch (java.net.MalformedURLException e) { throw new IOException("Cannot determine host from jar URL: " + url); } diff --git a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy index c140382f1b5..7723b524fb6 100644 --- a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy +++ b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy @@ -28,7 +28,7 @@ import org.apache.ofbiz.base.util.string.tool.TestingMap class FlexibleMapAccessorTest { - private static final Locale LOCALE_TO_TEST = new Locale('en', 'US') + private static final Locale LOCALE_TO_TEST = Locale.of('en', 'US') private static final FlexibleMapAccessor EMPTY_FMA = FlexibleMapAccessor.getInstance('') private static final FlexibleMapAccessor NULL_FMA = FlexibleMapAccessor.getInstance(null) diff --git a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy index 737e0b6891a..e5d05d6b4be 100644 --- a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy +++ b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy @@ -30,8 +30,8 @@ import org.junit.jupiter.api.Test */ class FlexibleStringExpanderTests { - private static final Locale LOCALE_TO_TEST = new Locale('en', 'US') - private static final Locale OTHER_LOCALE = new Locale('fr') + private static final Locale LOCALE_TO_TEST = Locale.of('en', 'US') + private static final Locale OTHER_LOCALE = Locale.of('fr') private static final TimeZone TIME_ZONE_TO_TEST = TimeZone.getTimeZone('PST') private static final TimeZone OTHER_TIME_ZONE = TimeZone.getTimeZone('GMT') diff --git a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java index fd36a1cfc26..0b5a107e2b2 100644 --- a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java +++ b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java @@ -42,7 +42,7 @@ public void checkStringForHtmlStrictNoneDetectsXSS() { String xssVector = "<script>alert(\"XSS vector\");</script>"; List errorList = new ArrayList<>(); String canonicalizedXssVector = UtilCodec.checkStringForHtmlStrictNone("fieldName", xssVector, errorList, - new Locale("test")); // labels are not available in testClasses Gradle task + Locale.of("test")); // labels are not available in testClasses Gradle task assertEquals("", canonicalizedXssVector); assertEquals(1, errorList.size()); assertEquals("In field [fieldName] less-than (<) and greater-than (>) symbols are not allowed.", @@ -91,7 +91,7 @@ private static void checkStringForHtmlStrictNoneTest(String label, String fixed, String... wantedMessages) { List gottenMessages = new ArrayList<>(); assertEquals(fixed, UtilCodec.checkStringForHtmlStrictNone(label, input, gottenMessages, - new Locale("test")), label); // labels are not available in testClasses Gradle task + Locale.of("test")), label); // labels are not available in testClasses Gradle task assertEquals(Arrays.asList(wantedMessages), gottenMessages, label); } @@ -100,7 +100,7 @@ public void testCheckStringForHtmlSafe() { String xssVector = ""; List errorList = new ArrayList<>(); String canonicalizedXssVector = UtilCodec.checkStringForHtmlSafe("fieldName", xssVector, errorList, - new Locale("test"), true); // labels are not available in testClasses Gradle task + Locale.of("test"), true); // labels are not available in testClasses Gradle task assertEquals("", canonicalizedXssVector); assertEquals(1, errorList.size()); assertEquals("In field [fieldName] by our input policy, your input has not been accepted for security reason. " diff --git a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java index c009cde2f77..94aba45dbaa 100644 --- a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java +++ b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java @@ -35,7 +35,7 @@ public class UtilPropertiesTests { private static final String COUNTRY = "AU"; private static final String LANGUAGE = "en"; - private final Locale locale = new Locale(LANGUAGE, COUNTRY); + private final Locale locale = Locale.of(LANGUAGE, COUNTRY); /** * Old style xml:lang attribute value was of form en_AU. Test this diff --git a/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java b/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java index c653128b572..79605ffe3c9 100644 --- a/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java +++ b/framework/common/src/main/java/org/apache/ofbiz/common/CommonEvents.java @@ -442,7 +442,7 @@ public static String openSourceFile(HttpServletRequest request, HttpServletRespo String cmd = (String) FlexibleStringExpander.getInstance(cmdTemplate).expand(sourceMap); // run command Debug.logInfo("Run command: " + cmd, MODULE); - Process process = Runtime.getRuntime().exec(cmd); + Process process = Runtime.getRuntime().exec(new String[]{cmd}); // print result BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java index d3afd8d3264..5e98f0ec66a 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java @@ -854,7 +854,7 @@ private void checkLockWaitInfo(Exception sqle) { // the string for Derby is "A lock could not be obtained within the time requested" // the string for MySQL is "Lock wait timeout exceeded; try restarting transaction" if (eMsg.contains("A lock could not be obtained within the time requested") || eMsg.contains("Lock wait timeout exceeded")) { - Debug.logWarning(sqle, "Lock wait timeout error found in thread [" + Thread.currentThread().getId() + "]: (" + eMsg + Debug.logWarning(sqle, "Lock wait timeout error found in thread [" + Thread.currentThread().threadId() + "]: (" + eMsg + ") when executing the SQL [" + sql + "]", MODULE); TransactionUtil.printAllThreadsTransactionBeginStacks(); } diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java index 7515c2f7136..a517d7e62da 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java @@ -660,7 +660,7 @@ private static void pushTransactionBeginStackSave(Exception e) { el.add(0, e); if (Debug.infoOn()) { - Long curThreadId = Thread.currentThread().getId(); + Long curThreadId = Thread.currentThread().threadId(); List ctEl = allThreadsTransactionBeginStackSave.get(curThreadId); if (ctEl == null) { ctEl = new LinkedList<>(); @@ -673,7 +673,7 @@ private static void pushTransactionBeginStackSave(Exception e) { private static Exception popTransactionBeginStackSave() { if (Debug.infoOn()) { // do the unofficial all threads Map one first, and don't do a real return - Long curThreadId = Thread.currentThread().getId(); + Long curThreadId = Thread.currentThread().threadId(); List ctEl = allThreadsTransactionBeginStackSave.get(curThreadId); if (UtilValidate.isNotEmpty(ctEl)) { ctEl.remove(0); @@ -751,14 +751,14 @@ private static void setTransactionBeginStack(Exception newExc) { } transactionBeginStack.set(newExc); if (Debug.infoOn()) { - Long curThreadId = Thread.currentThread().getId(); + Long curThreadId = Thread.currentThread().threadId(); allThreadsTransactionBeginStack.put(curThreadId, newExc); } } private static Exception clearTransactionBeginStack() { if (Debug.infoOn()) { - Long curThreadId = Thread.currentThread().getId(); + Long curThreadId = Thread.currentThread().threadId(); allThreadsTransactionBeginStack.remove(curThreadId); } Exception e = transactionBeginStack.get(); diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityDataLoader.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityDataLoader.java index 31c42c319a8..58994655933 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityDataLoader.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityDataLoader.java @@ -225,23 +225,23 @@ public static List getUrlByComponentList(String helperName, List co return getUrlByComponentList(helperName, components, readerNames); } - public static int loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages) throws GenericEntityException { + public static long loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages) throws GenericEntityException { return loadData(dataUrl, helperName, delegator, errorMessages, -1); } - public static int loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages, int txTimeout) + public static long loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages, int txTimeout) throws GenericEntityException { return loadData(dataUrl, helperName, delegator, errorMessages, txTimeout, false, false, false); } - public static int loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages, int txTimeout, boolean dummyFks, + public static long loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages, int txTimeout, boolean dummyFks, boolean maintainTxs, boolean tryInsert) throws GenericEntityException { return loadData(dataUrl, helperName, delegator, errorMessages, txTimeout, false, false, false, true); } - public static int loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages, int txTimeout, boolean dummyFks, + public static long loadData(URL dataUrl, String helperName, Delegator delegator, List errorMessages, int txTimeout, boolean dummyFks, boolean maintainTxs, boolean tryInsert, boolean continueOnFail) throws GenericEntityException { - int rowsChanged = 0; + long rowsChanged = 0; if (dataUrl == null) { String errMsg = "Cannot load data, dataUrl was null"; @@ -264,7 +264,7 @@ public static int loadData(URL dataUrl, String helperName, Delegator delegator, reader.setCreateDummyFks(dummyFks); reader.setMaintainTxStamps(maintainTxs); reader.setContinueOnFail(continueOnFail); - rowsChanged += (int) reader.parse(dataUrl); + rowsChanged += reader.parse(dataUrl); } catch (IOException | SAXException e) { String xmlError = "[loadData]: Error loading XML Resource \"" + dataUrl.toExternalForm() + "\"; Error was: " + e.getMessage(); errorMessages.add(xmlError); diff --git a/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java b/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java index e740865ecda..975fe8c23bf 100644 --- a/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java +++ b/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java @@ -423,13 +423,13 @@ private static void loadData(Delegator delegator, Delegator baseDelegator, List urlList = prepareDataUrls(delegator, baseDelegator, allComponents, helperInfo, loadDataProps); List infoMessages = new ArrayList<>(); List errorMessages = new ArrayList<>(); - int totalRowsChanged = 0; + long totalRowsChanged = 0; logDataLoadingPlan(urlList, delegator.getDelegatorName()); for (URL dataUrl: urlList) { try { - int rowsChanged = EntityDataLoader.loadData(dataUrl, helperInfo.getHelperBaseName(), + long rowsChanged = EntityDataLoader.loadData(dataUrl, helperInfo.getHelperBaseName(), delegator, errorMessages, txTimeout, useDummyFks, maintainTxs, tryInserts, continueOnFail); totalRowsChanged += rowsChanged; infoMessages.add(createDataLoadMessage(dataUrl, rowsChanged, totalRowsChanged)); @@ -570,7 +570,7 @@ private static void logDataLoadingPlan(List urlList, String delegatorName) } } - private static String createDataLoadMessage(URL dataUrl, int rowsChanged, int totalRowsChanged) { + private static String createDataLoadMessage(URL dataUrl, long rowsChanged, long totalRowsChanged) { NumberFormat formatter = NumberFormat.getIntegerInstance(); formatter.setMinimumIntegerDigits(5); formatter.setGroupingUsed(false); @@ -580,7 +580,7 @@ private static String createDataLoadMessage(URL dataUrl, int rowsChanged, int to } private static void logDataLoadingResults(List infoMessages, - List errorMessages, int totalRowsChanged) { + List errorMessages, long totalRowsChanged) { if (UtilValidate.isNotEmpty(infoMessages)) { Debug.logImportant("=-=-=-=-=-=-= Here is a summary of the data load:", MODULE); diff --git a/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java b/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java index 315b4ae0f7e..a32c8d94e79 100644 --- a/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java +++ b/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java @@ -189,13 +189,13 @@ private static Locale getDefaultLocale(Properties props, String defaultLocale) { Locale locale = null; switch (locales.length) { case 1: - locale = new Locale(locales[0]); + locale = Locale.of(locales[0]); break; case 2: - locale = new Locale(locales[0], locales[1]); + locale = Locale.of(locales[0], locales[1]); break; case 3: - locale = new Locale(locales[0], locales[1], locales[2]); + locale = Locale.of(locales[0], locales[1], locales[2]); break; default: throw new IllegalArgumentException("The combination of properties, ofbiz.locale.default and defaultLocale is invalid. " diff --git a/framework/testtools/src/main/java/org/apache/ofbiz/testtools/EntityXmlAssertTest.java b/framework/testtools/src/main/java/org/apache/ofbiz/testtools/EntityXmlAssertTest.java index a7f4e036d68..f750969cdc9 100644 --- a/framework/testtools/src/main/java/org/apache/ofbiz/testtools/EntityXmlAssertTest.java +++ b/framework/testtools/src/main/java/org/apache/ofbiz/testtools/EntityXmlAssertTest.java @@ -53,6 +53,7 @@ public EntityXmlAssertTest(String caseName, Element mainElement) { } @Override + @SuppressWarnings("lossy-conversions") public int countTestCases() { int testCaseCount = 0; try { diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/JWTManager.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/JWTManager.java index 123d9584dd5..08ed1cf1960 100644 --- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/JWTManager.java +++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/JWTManager.java @@ -19,7 +19,7 @@ package org.apache.ofbiz.webapp.control; import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; import java.security.interfaces.RSAPublicKey; import java.sql.Timestamp; import java.util.Calendar; @@ -83,7 +83,7 @@ private static JwkProvider getJwkProvider(Delegator delegator) throws IllegalSta if (localRef == null) { String issuer = EntityUtilProperties.getPropertyValue("security", "security.token.issuer", "", delegator); String jwksUrl = issuer + "/protocol/openid-connect/certs"; - localRef = new JwkProviderBuilder(new URL(jwksUrl)) + localRef = new JwkProviderBuilder(URI.create(jwksUrl).toURL()) .cached(10, 24, TimeUnit.HOURS) // cache up to 10 keys for 24h .rateLimited(10, 1, TimeUnit.MINUTES) // prevent frequent fetches .build(); diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java index 480555cd9cb..25c8569d4aa 100644 --- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java +++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java @@ -192,7 +192,7 @@ public void close() throws IOException { // we set the max to 10 digits as an hack to not round numbers in the ui } } else { - out.write(UtilFormatOut.formatCurrency(amount, isoCode, new Locale(locale), rounding)); + out.write(UtilFormatOut.formatCurrency(amount, isoCode, Locale.of(locale), rounding)); // we set the max to 10 digits as an hack to not round numbers in the ui } } catch (TemplateModelException e) { diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java index 38372e435cc..d111bd1a890 100644 --- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java +++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java @@ -135,7 +135,7 @@ public void close() throws IOException { localeObj = env.getLocale(); } } else { - localeObj = new Locale(locale); + localeObj = Locale.of(locale); } out.write(UtilFormatOut.formatNumber(number, format, delegator, localeObj)); } catch (TemplateModelException e) { diff --git a/framework/webtools/src/main/java/org/apache/ofbiz/webtools/WebToolsServices.java b/framework/webtools/src/main/java/org/apache/ofbiz/webtools/WebToolsServices.java index 6f9fda106ad..9f3de0db26f 100644 --- a/framework/webtools/src/main/java/org/apache/ofbiz/webtools/WebToolsServices.java +++ b/framework/webtools/src/main/java/org/apache/ofbiz/webtools/WebToolsServices.java @@ -414,7 +414,7 @@ public static Map entityImportReaders(DispatchContext dctx, Map< List errorMessages = new LinkedList<>(); List infoMessages = new LinkedList<>(); - int totalRowsChanged = 0; + long totalRowsChanged = 0; if (UtilValidate.isNotEmpty(urlList)) { messages.add("=-=-=-=-=-=-= Doing a data " + (checkDataOnly ? "check" : "load") + " with the following files:"); for (URL dataUrl : urlList) { @@ -425,7 +425,7 @@ public static Map entityImportReaders(DispatchContext dctx, Map< for (URL dataUrl : urlList) { try { - int rowsChanged = 0; + long rowsChanged = 0; if (checkDataOnly) { try { errorMessages.add("Checking data in [" + dataUrl.toExternalForm() + "]"); diff --git a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java index b8f7193b9ef..51be3c54d9b 100644 --- a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java +++ b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java @@ -613,7 +613,7 @@ public void dateRangePickerField(@Mocked final ModelFormField.DateRangePickerFie }; final Map context = new HashMap<>(); - context.put("locale", new Locale("fr")); + context.put("locale", Locale.of("fr")); final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.dateRangePicker(context, dateRangePickerField); assertThat(renderableFtl, MacroCallMatcher.hasName("renderDateRangePicker")); diff --git a/gradle.properties b/gradle.properties index 0b89105a14d..c005081ab4f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,9 +18,9 @@ ############################################################################### org.gradle.console=plain -# If you experience heap memory problems during the Gradle build, for example -# building with integrated plugins, the following setting might help -#org.gradle.jvmargs=-Xms128m -Xmx1024m -XX:+CMSClassUnloadingEnabled +# JVM args for the Gradle daemon process (not the OFBiz JVM ? those are in build.gradle applicationDefaultJvmArgs). +# Increase Xmx if you experience heap memory problems during the Gradle build (e.g. with integrated plugins). +org.gradle.jvmargs=-Xms256m -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # Uncomment to disable source line numbers in log output (e.g. for production). #systemProp.ofbiz.env=prod From a0bad5f345477e41d0e5243d69e2ff1d91d47a38 Mon Sep 17 00:00:00 2001 From: Ashish Vijaywargiya Date: Wed, 15 Jul 2026 23:43:36 +0530 Subject: [PATCH 2/4] Changing the java version from 17 to 21 in gradle.yml file. Build process in PR is not working as expected. --- .github/workflows/gradle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 56915a8e270..cb9bb7ea7dc 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -40,10 +40,10 @@ jobs: - name: Check out OFBiz sources uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 with: - java-version: 17 + java-version: 21 distribution: temurin cache: 'gradle' From 5454391253bba2200dc3c249e50cd7a34604bfbb Mon Sep 17 00:00:00 2001 From: Ashish Vijaywargiya Date: Thu, 16 Jul 2026 14:48:54 +0530 Subject: [PATCH 3/4] Added the support of Java17 and Java21 in ofbiz trunk code base. This fix can go on for a long run and we can take whatever time we need for switching the project trunk codebase on Java21. --- .../jobshopmgt/ProductionRunContent.groovy | 2 +- .../workeffort/WorkEffortServices.java | 3 ++- build.gradle | 16 ++++++++++------ .../org/apache/ofbiz/base/util/UtilCodec.java | 13 ++++++++----- .../org/apache/ofbiz/base/util/UtilMisc.java | 3 ++- .../org/apache/ofbiz/base/util/UtilNumber.java | 6 ++++-- .../apache/ofbiz/base/util/UtilProperties.java | 3 ++- .../collection/FlexibleMapAccessorTest.groovy | 2 +- .../string/FlexibleStringExpanderTests.groovy | 4 ++-- .../apache/ofbiz/base/util/UtilCodecTests.java | 10 +++++++--- .../ofbiz/base/util/UtilPropertiesTests.java | 3 ++- .../apache/ofbiz/entity/jdbc/SQLProcessor.java | 3 ++- .../entity/transaction/TransactionUtil.java | 12 ++++++++---- .../java/org/apache/ofbiz/base/start/Config.java | 7 ++++--- .../ofbiz/webapp/ftl/OfbizCurrencyTransform.java | 3 ++- .../ofbiz/webapp/ftl/OfbizNumberTransform.java | 3 ++- .../RenderableFtlFormElementsBuilderTest.java | 3 ++- 17 files changed, 61 insertions(+), 35 deletions(-) diff --git a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy index 52164a1ee1a..4be5a7661c6 100644 --- a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy +++ b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunContent.groovy @@ -37,7 +37,7 @@ if (context.delivProductId && (parameters.partyId || parameters.contentLocale)) Locale contentLocale = null if (parameters.contentLocale) { - contentLocale = Locale.of(parameters.contentLocale) + contentLocale = new Locale(parameters.contentLocale) } delivProductContentsForLocaleAndUser = [] delivProductContents.each { delivProductContent -> diff --git a/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java b/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java index 485e7e7f5ee..9f65de4f2ed 100644 --- a/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java +++ b/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java @@ -953,7 +953,8 @@ public static Map processWorkEffortEventReminders(DispatchContex } continue; } - Locale locale = reminder.getString("localeId") == null ? Locale.getDefault() : Locale.of(reminder.getString("localeId")); + @SuppressWarnings("deprecation") + Locale locale = reminder.getString("localeId") == null ? Locale.getDefault() : new Locale(reminder.getString("localeId")); TimeZone timeZone = reminder.getString("timeZoneId") == null ? TimeZone.getDefault() : TimeZone.getTimeZone(reminder.getString("timeZoneId")); Map parameters = UtilMisc.toMap("locale", locale, "timeZone", timeZone, "workEffortId", reminder.get("workEffortId")); diff --git a/build.gradle b/build.gradle index 77ddacac414..dde39621c9f 100644 --- a/build.gradle +++ b/build.gradle @@ -141,13 +141,13 @@ javadoc { title="OFBiz " + getCurrentGitBranch() + " API" failOnError = true options { - source '21' + source '17' encoding 'UTF-8' charSet 'UTF-8' // Those external Javadoc links should correspond to the actual // versions declared in the 'dependencies' block. links( - 'https://docs.oracle.com/en/java/javase/21/docs/api/', + 'https://docs.oracle.com/en/java/javase/17/docs/api/', 'https://tomcat.apache.org/tomcat-10.1-doc/servletapi/', 'http://docs.groovy-lang.org/docs/groovy-4.0.22/html/api', 'https://commons.apache.org/proper/commons-cli/apidocs' @@ -159,8 +159,8 @@ javadoc { } java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } // Java compile options, syntax gradlew -PXlint:none build @@ -170,8 +170,12 @@ tasks.withType(JavaCompile) { options.compilerArgs << '-Xlint:all' // Exclude varargs warnings which are not silenced by @SafeVarargs. options.compilerArgs << '-Xlint:-varargs' - // Exclude this-escape warnings pending proper refactoring of widget/service classes. - options.compilerArgs << '-Xlint:-this-escape' + // this-escape lint was introduced in JDK 21's javac and is an invalid flag on JDK 17, + // so only pass it when compiling with a JDK that recognizes it. + if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) { + // Exclude this-escape warnings pending proper refactoring of widget/service classes. + options.compilerArgs << '-Xlint:-this-escape' + } } } diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java index 099b1f237a5..2f37c0ddebf 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilCodec.java @@ -53,6 +53,9 @@ @SuppressWarnings("rawtypes") public class UtilCodec { private static final String MODULE = UtilCodec.class.getName(); + // sentinel locale used because labels are not available in the testClasses Gradle task + @SuppressWarnings("deprecation") + private static final Locale TEST_LOCALE = new Locale("test"); private static final HtmlEncoder HTML_ENCODER = new HtmlEncoder(); private static final XmlEncoder XML_ENCODER = new XmlEncoder(); private static final StringEncoder STRING_ENCODER = new StringEncoder(); @@ -435,7 +438,7 @@ public static String checkStringForHtmlStrictNone(String valueName, String value Debug.logError("Canonicalization (format consistency, character escaping that is mixed or double, etc) " + "error for attribute named [" + valueName + "], String [" + value + "]: " + e.toString(), MODULE); String issueMsg = null; - if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(TEST_LOCALE)) { issueMsg = "In field [" + valueName + "] found character escaping (mixed or double) " + "that is not allowed or other format consistency error: "; } else { @@ -448,7 +451,7 @@ public static String checkStringForHtmlStrictNone(String valueName, String value // check for "<", ">" if (value.indexOf("<") >= 0 || value.indexOf(">") >= 0) { String issueMsg = null; - if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(TEST_LOCALE)) { issueMsg = "In field [" + valueName + "] less-than (<) and greater-than (>) symbols are not allowed."; } else { issueMsg = UtilProperties.getMessage("SecurityUiLabels", "PolicyNoneLess-thanGreater-than", @@ -463,7 +466,7 @@ public static String checkStringForHtmlStrictNone(String valueName, String value if (JS_EVENT_LIST.stream().anyMatch(s -> s.toLowerCase(Locale.ROOT).contains(onEventLower)) || value.contains("seekSegmentTime")) { String issueMsg = null; - if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(TEST_LOCALE)) { issueMsg = "In field [" + valueName + "] Javascript events are not allowed."; } else { issueMsg = UtilProperties.getMessage("SecurityUiLabels", "PolicyNoneJsEvents", @@ -501,7 +504,7 @@ public static String checkStringForHtmlSafe(String valueName, String value, List PolicyFactory policy = null; try { Class customPolicyClass = null; - if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(TEST_LOCALE)) { customPolicyClass = Class.forName("org.apache.ofbiz.base.html.CustomSafePolicy"); } else { customPolicyClass = Class.forName(UtilProperties.getPropertyValue("owasp", "sanitizer.custom.safe.policy.class")); @@ -566,7 +569,7 @@ public void closeDocument() { // Maybe later we will figure out that some more HTML entities will need to be added to here, see OFBIZ-12691 if (filtered != null && !value.replace("'", "'").replace(""", "\"").replace("@", "@").equals(unescapeEcmaScriptAndHtml4)) { String issueMsg = null; - if (locale.equals(Locale.of("test"))) { // labels are not available in testClasses Gradle task + if (locale.equals(TEST_LOCALE)) { issueMsg = "In field [" + valueName + "] by our input policy, your input has not been accepted " + "for security reason. Please check and modify accordingly, thanks."; } else { diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java index b0b70fc4596..c5caccf742e 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilMisc.java @@ -550,6 +550,7 @@ public static void addToDoubleInMap(Map theMap, K key, Double val * @param localeString The locale string (en_US) * @return Locale The new Locale object or null if no valid locale can be interpreted */ + @SuppressWarnings("deprecation") public static Locale parseLocale(String localeString) { if (UtilValidate.isEmpty(localeString)) { return null; @@ -569,7 +570,7 @@ public static Locale parseLocale(String localeString) { String language = localeString.substring(0, 2); String country = localeString.substring(3, 5); String extension = localeString.substring(6); - locale = Locale.of(language, country, extension); + locale = new Locale(language, country, extension); } else { Debug.logWarning("Do not know what to do with the localeString [" + localeString + "], should be length 2, 5, or greater than 6, " + "returning null", MODULE); diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java index e62dafe7f08..dbd21ff6640 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilNumber.java @@ -172,8 +172,10 @@ public final class UtilNumber { static { rbnfRuleSets = new HashMap<>(); rbnfRuleSets.put(Locale.US, RULE_SET_EN_US); - rbnfRuleSets.put(Locale.of("th"), RULE_SET_TH_TH); - rbnfRuleSets.put(Locale.of("en", "IN"), RULE_SET_EN_IN); + @SuppressWarnings("deprecation") Locale thLocale = new Locale("th"); + @SuppressWarnings("deprecation") Locale enInLocale = new Locale("en", "IN"); + rbnfRuleSets.put(thLocale, RULE_SET_TH_TH); + rbnfRuleSets.put(enInLocale, RULE_SET_EN_IN); } private UtilNumber() { } diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java index 57a496d2ff7..5b3239e31e2 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilProperties.java @@ -751,6 +751,7 @@ public static Locale getFallbackLocale() { * a list containing en_US and en. * @return A list of candidate locales. */ + @SuppressWarnings("deprecation") public static List localeToCandidateList(Locale locale) { List localeList = new LinkedList<>(); localeList.add(locale); @@ -758,7 +759,7 @@ public static List localeToCandidateList(Locale locale) { int pos = localeString.lastIndexOf("_", localeString.length()); while (pos != -1) { localeString = localeString.substring(0, pos); - localeList.add(Locale.of(localeString)); + localeList.add(new Locale(localeString)); pos = localeString.lastIndexOf("_", localeString.length()); } return localeList; diff --git a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy index 7723b524fb6..c140382f1b5 100644 --- a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy +++ b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/collection/FlexibleMapAccessorTest.groovy @@ -28,7 +28,7 @@ import org.apache.ofbiz.base.util.string.tool.TestingMap class FlexibleMapAccessorTest { - private static final Locale LOCALE_TO_TEST = Locale.of('en', 'US') + private static final Locale LOCALE_TO_TEST = new Locale('en', 'US') private static final FlexibleMapAccessor EMPTY_FMA = FlexibleMapAccessor.getInstance('') private static final FlexibleMapAccessor NULL_FMA = FlexibleMapAccessor.getInstance(null) diff --git a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy index e5d05d6b4be..737e0b6891a 100644 --- a/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy +++ b/framework/base/src/test/groovy/org/apache/ofbiz/base/util/string/FlexibleStringExpanderTests.groovy @@ -30,8 +30,8 @@ import org.junit.jupiter.api.Test */ class FlexibleStringExpanderTests { - private static final Locale LOCALE_TO_TEST = Locale.of('en', 'US') - private static final Locale OTHER_LOCALE = Locale.of('fr') + private static final Locale LOCALE_TO_TEST = new Locale('en', 'US') + private static final Locale OTHER_LOCALE = new Locale('fr') private static final TimeZone TIME_ZONE_TO_TEST = TimeZone.getTimeZone('PST') private static final TimeZone OTHER_TIME_ZONE = TimeZone.getTimeZone('GMT') diff --git a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java index 0b5a107e2b2..9e1ef143770 100644 --- a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java +++ b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilCodecTests.java @@ -30,6 +30,10 @@ public class UtilCodecTests { + // sentinel locale used because labels are not available in the testClasses Gradle task + @SuppressWarnings("deprecation") + private static final Locale TEST_LOCALE = new Locale("test"); + @Test public void canonicalizeRevealsEscapedXSS() { String xssVector = "<script>alert(\"XSS vector\");</script>"; @@ -42,7 +46,7 @@ public void checkStringForHtmlStrictNoneDetectsXSS() { String xssVector = "<script>alert(\"XSS vector\");</script>"; List errorList = new ArrayList<>(); String canonicalizedXssVector = UtilCodec.checkStringForHtmlStrictNone("fieldName", xssVector, errorList, - Locale.of("test")); // labels are not available in testClasses Gradle task + TEST_LOCALE); assertEquals("", canonicalizedXssVector); assertEquals(1, errorList.size()); assertEquals("In field [fieldName] less-than (<) and greater-than (>) symbols are not allowed.", @@ -91,7 +95,7 @@ private static void checkStringForHtmlStrictNoneTest(String label, String fixed, String... wantedMessages) { List gottenMessages = new ArrayList<>(); assertEquals(fixed, UtilCodec.checkStringForHtmlStrictNone(label, input, gottenMessages, - Locale.of("test")), label); // labels are not available in testClasses Gradle task + TEST_LOCALE), label); assertEquals(Arrays.asList(wantedMessages), gottenMessages, label); } @@ -100,7 +104,7 @@ public void testCheckStringForHtmlSafe() { String xssVector = ""; List errorList = new ArrayList<>(); String canonicalizedXssVector = UtilCodec.checkStringForHtmlSafe("fieldName", xssVector, errorList, - Locale.of("test"), true); // labels are not available in testClasses Gradle task + TEST_LOCALE, true); assertEquals("", canonicalizedXssVector); assertEquals(1, errorList.size()); assertEquals("In field [fieldName] by our input policy, your input has not been accepted for security reason. " diff --git a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java index 94aba45dbaa..0006b010600 100644 --- a/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java +++ b/framework/base/src/test/java/org/apache/ofbiz/base/util/UtilPropertiesTests.java @@ -35,7 +35,8 @@ public class UtilPropertiesTests { private static final String COUNTRY = "AU"; private static final String LANGUAGE = "en"; - private final Locale locale = Locale.of(LANGUAGE, COUNTRY); + @SuppressWarnings("deprecation") + private final Locale locale = new Locale(LANGUAGE, COUNTRY); /** * Old style xml:lang attribute value was of form en_AU. Test this diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java index 5e98f0ec66a..17ca5c4b25e 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java @@ -847,6 +847,7 @@ protected void setFetchSize(Statement stmt, int fetchSize) throws SQLException { } } + @SuppressWarnings("deprecation") private void checkLockWaitInfo(Exception sqle) { String eMsg = sqle.getMessage(); @@ -854,7 +855,7 @@ private void checkLockWaitInfo(Exception sqle) { // the string for Derby is "A lock could not be obtained within the time requested" // the string for MySQL is "Lock wait timeout exceeded; try restarting transaction" if (eMsg.contains("A lock could not be obtained within the time requested") || eMsg.contains("Lock wait timeout exceeded")) { - Debug.logWarning(sqle, "Lock wait timeout error found in thread [" + Thread.currentThread().threadId() + "]: (" + eMsg + Debug.logWarning(sqle, "Lock wait timeout error found in thread [" + Thread.currentThread().getId() + "]: (" + eMsg + ") when executing the SQL [" + sql + "]", MODULE); TransactionUtil.printAllThreadsTransactionBeginStacks(); } diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java index a517d7e62da..626648668b1 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/transaction/TransactionUtil.java @@ -650,6 +650,7 @@ protected static void removeSuspendedTransaction(Transaction t) { // ======================================= // TRANSACTION BEGIN STACK // ======================================= + @SuppressWarnings("deprecation") private static void pushTransactionBeginStackSave(Exception e) { // use the ThreadLocal one because it is more reliable than the all threads Map List el = transactionBeginStackSave.get(); @@ -660,7 +661,7 @@ private static void pushTransactionBeginStackSave(Exception e) { el.add(0, e); if (Debug.infoOn()) { - Long curThreadId = Thread.currentThread().threadId(); + Long curThreadId = Thread.currentThread().getId(); List ctEl = allThreadsTransactionBeginStackSave.get(curThreadId); if (ctEl == null) { ctEl = new LinkedList<>(); @@ -670,10 +671,11 @@ private static void pushTransactionBeginStackSave(Exception e) { } } + @SuppressWarnings("deprecation") private static Exception popTransactionBeginStackSave() { if (Debug.infoOn()) { // do the unofficial all threads Map one first, and don't do a real return - Long curThreadId = Thread.currentThread().threadId(); + Long curThreadId = Thread.currentThread().getId(); List ctEl = allThreadsTransactionBeginStackSave.get(curThreadId); if (UtilValidate.isNotEmpty(ctEl)) { ctEl.remove(0); @@ -741,6 +743,7 @@ private static void setTransactionBeginStack() { setTransactionBeginStack(e); } + @SuppressWarnings("deprecation") private static void setTransactionBeginStack(Exception newExc) { if (transactionBeginStack.get() != null) { Exception e = transactionBeginStack.get(); @@ -751,14 +754,15 @@ private static void setTransactionBeginStack(Exception newExc) { } transactionBeginStack.set(newExc); if (Debug.infoOn()) { - Long curThreadId = Thread.currentThread().threadId(); + Long curThreadId = Thread.currentThread().getId(); allThreadsTransactionBeginStack.put(curThreadId, newExc); } } + @SuppressWarnings("deprecation") private static Exception clearTransactionBeginStack() { if (Debug.infoOn()) { - Long curThreadId = Thread.currentThread().threadId(); + Long curThreadId = Thread.currentThread().getId(); allThreadsTransactionBeginStack.remove(curThreadId); } Exception e = transactionBeginStack.get(); diff --git a/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java b/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java index a32c8d94e79..b6e5f89380f 100644 --- a/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java +++ b/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java @@ -183,19 +183,20 @@ private static InetAddress getAdminAddress(String serverHost) throws StartupExce } } + @SuppressWarnings("deprecation") private static Locale getDefaultLocale(Properties props, String defaultLocale) { String localeString = getProperty(props, "ofbiz.locale.default", defaultLocale); String locales[] = localeString.split("_"); Locale locale = null; switch (locales.length) { case 1: - locale = Locale.of(locales[0]); + locale = new Locale(locales[0]); break; case 2: - locale = Locale.of(locales[0], locales[1]); + locale = new Locale(locales[0], locales[1]); break; case 3: - locale = Locale.of(locales[0], locales[1], locales[2]); + locale = new Locale(locales[0], locales[1], locales[2]); break; default: throw new IllegalArgumentException("The combination of properties, ofbiz.locale.default and defaultLocale is invalid. " diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java index 25c8569d4aa..5b2a17f7dc8 100644 --- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java +++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizCurrencyTransform.java @@ -174,6 +174,7 @@ public void flush() throws IOException { } @Override + @SuppressWarnings("deprecation") public void close() throws IOException { try { if (Debug.verboseOn()) { @@ -192,7 +193,7 @@ public void close() throws IOException { // we set the max to 10 digits as an hack to not round numbers in the ui } } else { - out.write(UtilFormatOut.formatCurrency(amount, isoCode, Locale.of(locale), rounding)); + out.write(UtilFormatOut.formatCurrency(amount, isoCode, new Locale(locale), rounding)); // we set the max to 10 digits as an hack to not round numbers in the ui } } catch (TemplateModelException e) { diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java index d111bd1a890..74a96d667f2 100644 --- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java +++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizNumberTransform.java @@ -116,6 +116,7 @@ public void flush() throws IOException { } @Override + @SuppressWarnings("deprecation") public void close() throws IOException { try { if (Debug.verboseOn()) { @@ -135,7 +136,7 @@ public void close() throws IOException { localeObj = env.getLocale(); } } else { - localeObj = Locale.of(locale); + localeObj = new Locale(locale); } out.write(UtilFormatOut.formatNumber(number, format, delegator, localeObj)); } catch (TemplateModelException e) { diff --git a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java index 51be3c54d9b..25452442d07 100644 --- a/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java +++ b/framework/widget/src/test/java/org/apache/ofbiz/widget/renderer/macro/RenderableFtlFormElementsBuilderTest.java @@ -613,7 +613,8 @@ public void dateRangePickerField(@Mocked final ModelFormField.DateRangePickerFie }; final Map context = new HashMap<>(); - context.put("locale", Locale.of("fr")); + @SuppressWarnings("deprecation") Locale locale = new Locale("fr"); + context.put("locale", locale); final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.dateRangePicker(context, dateRangePickerField); assertThat(renderableFtl, MacroCallMatcher.hasName("renderDateRangePicker")); From ca93c46fc112ee3b8d82303954812581858141a5 Mon Sep 17 00:00:00 2001 From: Ashish Vijaywargiya Date: Thu, 16 Jul 2026 14:54:12 +0530 Subject: [PATCH 4/4] Adding the java version support based on matrix in gradle.yml file. The default version is kept to java17 in trunk code base. And trunk code base build, run and performed test cases fine with java17 and java21 --- .github/workflows/gradle.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index cb9bb7ea7dc..35f52b9bbbd 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -30,6 +30,15 @@ permissions: jobs: build: + # trunk builds sourceCompatibility/targetCompatibility 17 bytecode (see build.gradle), + # but is matrix-tested on both the JDK 17 runtime it targets and the JDK 21 runtime + # it may adopt later. release* branches stay JDK 17 only until they make that same move, + # since trunk fixes must stay backportable to them. + if: ${{ !(matrix.java == 21 && ((github.event_name == 'push' && startsWith(github.ref_name, 'release')) || (github.event_name == 'pull_request' && startsWith(github.base_ref, 'release')))) }} + strategy: + fail-fast: false + matrix: + java: [ 17, 21 ] runs-on: ubuntu-latest @@ -40,10 +49,10 @@ jobs: - name: Check out OFBiz sources uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Set up JDK 21 + - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 with: - java-version: 21 + java-version: ${{ matrix.java }} distribution: temurin cache: 'gradle'