From a49bb925c3625b50bf8da37a47183370118d7147 Mon Sep 17 00:00:00 2001 From: Ashish Vijaywargiya Date: Sun, 10 May 2026 10:44:30 +0530 Subject: [PATCH 1/3] Add default H2 database support for OFBiz and removing the support of Apache Derby database as it's retiring/deprecating --- build.gradle | 4 +- dependencies.gradle | 3 +- docker/templates/postgres-entityengine.xml | 2 +- framework/base/config/passwords.properties | 8 +- framework/entity/config/entityengine.xml | 82 +++++++++---------- .../{fieldtypederby.xml => fieldtypeh2.xml} | 0 .../apache/ofbiz/entity/GenericDelegator.java | 20 ++++- .../ofbiz/entity/model/ModelEntity.java | 2 +- .../ofbiz/entity/DelegatorUnitTests.java | 1 - ...ta-Derby.xml => AdminNewTenantData-H2.xml} | 6 +- .../ofbiz/service/ModelServiceTest.groovy | 1 - .../org/apache/ofbiz/base/start/Config.java | 2 - .../apache/ofbiz/base/start/start.properties | 3 - .../ofbiz/webtools/WebToolsServices.java | 2 +- runtime/data/derby.properties | 28 ------- 15 files changed, 72 insertions(+), 92 deletions(-) rename framework/entity/fieldtype/{fieldtypederby.xml => fieldtypeh2.xml} (100%) rename framework/resources/templates/{AdminNewTenantData-Derby.xml => AdminNewTenantData-H2.xml} (80%) delete mode 100644 runtime/data/derby.properties diff --git a/build.gradle b/build.gradle index eb11a9578ec..1202bb07f63 100644 --- a/build.gradle +++ b/build.gradle @@ -971,8 +971,8 @@ task pullPlugin(group: ofbizPlugin, description: 'Download and install a plugin task cleanCatalina(group: cleanupGroup, description: 'Clean Catalina data in runtime/catalina/work') { doLast { delete "${rootDir}/runtime/catalina/work" } } -task cleanData(group: cleanupGroup, description: 'Clean all DB data (Derby) under runtime/data') { - doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/data/", ['README', 'derby.properties']) } +task cleanData(group: cleanupGroup, description: 'Clean all DB data (H2) under runtime/data') { + doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/data/", ['README', '.h2.server.properties']) } } task cleanDownloads(group: cleanupGroup, description: 'Clean all downloaded files') { doLast { diff --git a/dependencies.gradle b/dependencies.gradle index 62d7e5b5a2e..1579b59a16a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -97,8 +97,7 @@ dependencies { runtimeOnly 'org.apache.avalon.framework:avalon-framework-impl:4.3.1' runtimeOnly 'org.apache.axis2:axis2-transport-http:1.8.2' runtimeOnly 'org.apache.axis2:axis2-transport-local:1.8.2' - runtimeOnly 'org.apache.derby:derby:10.16.1.1' // 10.17.x.x requires Java 21 - runtimeOnly 'org.apache.derby:derbytools:10.16.1.1' // 10.17.x.x requires Java 21 + runtimeOnly 'com.h2database:h2:2.2.224' 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 diff --git a/docker/templates/postgres-entityengine.xml b/docker/templates/postgres-entityengine.xml index b9485c3407e..e22488e3af2 100644 --- a/docker/templates/postgres-entityengine.xml +++ b/docker/templates/postgres-entityengine.xml @@ -50,7 +50,7 @@ access. For a detailed description see the core/docs/entityconfig.html file. - + diff --git a/framework/base/config/passwords.properties b/framework/base/config/passwords.properties index 354aa96d711..755fdd0166e 100644 --- a/framework/base/config/passwords.properties +++ b/framework/base/config/passwords.properties @@ -17,7 +17,7 @@ # under the License. ############################################################################### -jdbc-password.derby-ofbiz=ofbiz -jdbc-password.derby-ofbizodbc=ofbiz -jdbc-password.derby-ofbizolap=ofbiz -jdbc-password.derby-ofbiztenant=ofbiz +jdbc-password.h2-ofbiz=ofbiz +jdbc-password.h2-ofbizodbc=ofbiz +jdbc-password.h2-ofbizolap=ofbiz +jdbc-password.h2-ofbiztenant=ofbiz diff --git a/framework/entity/config/entityengine.xml b/framework/entity/config/entityengine.xml index 6c3cac69324..c736aa3822c 100644 --- a/framework/entity/config/entityengine.xml +++ b/framework/entity/config/entityengine.xml @@ -52,22 +52,22 @@ access. For a detailed description see the core/docs/entityconfig.html file. - - - + + + - - - + + + - - - + + + @@ -98,7 +98,7 @@ access. For a detailed description see the core/docs/entityconfig.html file. - + @@ -157,10 +157,10 @@ access. For a detailed description see the core/docs/entityconfig.html file. - - + - + - - + - + - - + @@ -232,20 +232,20 @@ access. For a detailed description see the core/docs/entityconfig.html file. - + - - + - + - + groupNames = getModelGroupReader().getGroupNames(delegatorBaseName); - List> futures = new LinkedList<>(); + Map> helperGroups = new HashMap<>(); for (String groupName: groupNames) { - futures.add(ExecutionPool.GLOBAL_BATCH.submit(createHelperCallable(groupName))); + GenericHelperInfo helperInfo = this.getGroupHelperInfo(groupName); + String helperName = helperInfo != null ? helperInfo.getHelperFullName() : groupName; + helperGroups.computeIfAbsent(helperName, k -> new LinkedList<>()).add(groupName); } + + List> futures = new LinkedList<>(); + futures.add(ExecutionPool.GLOBAL_BATCH.submit(() -> { + for (List groupNamesForHelper : helperGroups.values()) { + for (String groupName : groupNamesForHelper) { + try { + createHelperCallable(groupName).call(); + } catch (Exception e) { + Debug.logError(e, MODULE); + } + } + } + return null; + })); ExecutionPool.getAllFutures(futures); // NOTE: doing some things before the ECAs and such to make sure it is in place just in case it is used in a service engine startup thing or diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/model/ModelEntity.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/model/ModelEntity.java index fa9a4065126..7e801dad537 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/model/ModelEntity.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/model/ModelEntity.java @@ -2174,7 +2174,7 @@ public Element toGroupXmlElement(Document document, String packageName) { public void writeEoModelText(PrintWriter writer, String entityPrefix, String helperName, Set entityNameIncludeSet, ModelReader entityModelReader) throws GenericEntityException { if (entityPrefix == null) entityPrefix = ""; - if (helperName == null) helperName = "localderby"; + if (helperName == null) helperName = "localh2"; UtilPlist.writePlistPropertyMap(this.createEoModelMap(entityPrefix, helperName, entityNameIncludeSet, entityModelReader), 0, writer, false); } diff --git a/framework/entity/src/test/java/org/apache/ofbiz/entity/DelegatorUnitTests.java b/framework/entity/src/test/java/org/apache/ofbiz/entity/DelegatorUnitTests.java index 5a873fec5da..b01e47c2f19 100644 --- a/framework/entity/src/test/java/org/apache/ofbiz/entity/DelegatorUnitTests.java +++ b/framework/entity/src/test/java/org/apache/ofbiz/entity/DelegatorUnitTests.java @@ -39,7 +39,6 @@ public class DelegatorUnitTests { @Before public void initialize() { System.setProperty("ofbiz.home", System.getProperty("user.dir")); - System.setProperty("derby.system.home", "./runtime/data/derby"); logErrorOn = Debug.isOn(Debug.ERROR); // save the current setting (to be restored after the tests) Debug.set(Debug.ERROR, false); // disable error logging } diff --git a/framework/resources/templates/AdminNewTenantData-Derby.xml b/framework/resources/templates/AdminNewTenantData-H2.xml similarity index 80% rename from framework/resources/templates/AdminNewTenantData-Derby.xml rename to framework/resources/templates/AdminNewTenantData-H2.xml index 39447b58172..2819d058277 100644 --- a/framework/resources/templates/AdminNewTenantData-Derby.xml +++ b/framework/resources/templates/AdminNewTenantData-H2.xml @@ -22,7 +22,7 @@ under the License. + jdbcUri="jdbc:h2:file:./runtime/data/h2/ofbiz_@tenantId@;AUTO_SERVER=TRUE" jdbcUsername="ofbiz" jdbcPassword="ofbiz"/> - \ No newline at end of file + jdbcUri="jdbc:h2:file:./runtime/data/h2/ofbizolap_@tenantId@;AUTO_SERVER=TRUE" jdbcUsername="ofbiz" jdbcPassword="ofbiz"/> + diff --git a/framework/service/src/test/groovy/org/apache/ofbiz/service/ModelServiceTest.groovy b/framework/service/src/test/groovy/org/apache/ofbiz/service/ModelServiceTest.groovy index b53764ed0b5..8d9e8af4c8d 100644 --- a/framework/service/src/test/groovy/org/apache/ofbiz/service/ModelServiceTest.groovy +++ b/framework/service/src/test/groovy/org/apache/ofbiz/service/ModelServiceTest.groovy @@ -46,7 +46,6 @@ class ModelServiceTest { @Before void initialize() { System.setProperty('ofbiz.home', System.getProperty('user.dir')) - System.setProperty('derby.system.home', './runtime/data/derby') dispatcher = Mockito.mock(LocalDispatcher) Mockito.when(dispatcher.getDelegator()).thenReturn(DelegatorFactory.getDelegator('default')) } 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 46eea95b24b..315b4ae0f7e 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 @@ -106,8 +106,6 @@ public Path getOfbizHome() { // set system properties System.setProperty("ofbiz.home", ofbizHome.toString()); System.setProperty("java.awt.headless", getProperty(props, "java.awt.headless", "true")); - System.setProperty("derby.system.home", getProperty(props, "derby.system.home", "runtime/data/derby")); - // set default locale and timezone Locale.setDefault(getDefaultLocale(props, "en")); TimeZone.setDefault(getDefaultTimeZone(props)); diff --git a/framework/start/src/main/resources/org/apache/ofbiz/base/start/start.properties b/framework/start/src/main/resources/org/apache/ofbiz/base/start/start.properties index 2be2171c460..7cc61948094 100644 --- a/framework/start/src/main/resources/org/apache/ofbiz/base/start/start.properties +++ b/framework/start/src/main/resources/org/apache/ofbiz/base/start/start.properties @@ -30,9 +30,6 @@ ofbiz.start.loaders=main # --- logs directory relative to ofbiz.home. Default is runtime/logs #ofbiz.log.dir= -# --- Derby directory relative to ofbiz.home. Default is runtime/data/derby -#derby.system.home= - # --- Container config file relative to ofbiz.home. # Default is framework/base/config/ofbiz-containers.xml #ofbiz.container.config= 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 bae2947d389..6f9fda106ad 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 @@ -855,7 +855,7 @@ public static Map exportEntityEoModelBundle(DispatchContext dctx String datasourceName = (String) context.get("datasourceName"); String entityNamePrefix = (String) context.get("entityNamePrefix"); Locale locale = (Locale) context.get("locale"); - if (datasourceName == null) datasourceName = "localderby"; + if (datasourceName == null) datasourceName = "localh2"; ModelReader reader = dctx.getDelegator().getModelReader(); diff --git a/runtime/data/derby.properties b/runtime/data/derby.properties deleted file mode 100644 index 6cba23ed130..00000000000 --- a/runtime/data/derby.properties +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################### -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -############################################################################### - -derby.infolog.append=true -derby.storage.pageSize=8192 -derby.storage.pageReservedSpace=60 -derby.storage.fileSyncTransactionLog=true - -# Useful for tracking down lock wait timeouts and deadlocks -#derby.locks.monitor=true -#derby.locks.deadlockTrace=true -#derby.language.logStatementText=true \ No newline at end of file From ebd2c9a1829e09e5e9898780d1900b52e6e0a0f0 Mon Sep 17 00:00:00 2001 From: Ashish Vijaywargiya Date: Sat, 16 May 2026 18:31:17 +0530 Subject: [PATCH 2/3] OFBiz was failing in the cleanAll loadAll. Did some adjustments in entityengine.xml to make h2 completely functional in OFBiz. --- framework/entity/config/entityengine.xml | 38 ++++++++++++++++-------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/framework/entity/config/entityengine.xml b/framework/entity/config/entityengine.xml index c736aa3822c..74ab1741a42 100644 --- a/framework/entity/config/entityengine.xml +++ b/framework/entity/config/entityengine.xml @@ -163,6 +163,7 @@ access. For a detailed description see the core/docs/entityconfig.html file. field-type-name="h2" check-on-start="true" add-missing-on-start="true" + max-worker-pool-size="1" use-pk-constraint-names="false" use-indices-unique="false" alias-view-columns="false" @@ -178,12 +179,13 @@ access. For a detailed description see the core/docs/entityconfig.html file. + pool-sleeptime="300000" + test-on-borrow="true" + pool-jdbc-test-stmt="SELECT 1" + time-between-eviction-runs-millis="600000"/> From e0d57773f1b00fe82f690fb784a224aaa4a46907 Mon Sep 17 00:00:00 2001 From: Ashish Vijaywargiya Date: Sat, 16 May 2026 18:52:24 +0530 Subject: [PATCH 3/3] Revert GenericDelegator.java to trunk version. The changes which I did are no more required. I was able to build the code by doing the changes only in entityengine.xml file --- .../apache/ofbiz/entity/GenericDelegator.java | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java index b5d651c523d..5e9c6f08e8c 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java @@ -247,26 +247,10 @@ protected GenericDelegator(String delegatorFullName) throws GenericEntityExcepti // initialize helpers by group Set groupNames = getModelGroupReader().getGroupNames(delegatorBaseName); - Map> helperGroups = new HashMap<>(); + List> futures = new LinkedList<>(); for (String groupName: groupNames) { - GenericHelperInfo helperInfo = this.getGroupHelperInfo(groupName); - String helperName = helperInfo != null ? helperInfo.getHelperFullName() : groupName; - helperGroups.computeIfAbsent(helperName, k -> new LinkedList<>()).add(groupName); + futures.add(ExecutionPool.GLOBAL_BATCH.submit(createHelperCallable(groupName))); } - - List> futures = new LinkedList<>(); - futures.add(ExecutionPool.GLOBAL_BATCH.submit(() -> { - for (List groupNamesForHelper : helperGroups.values()) { - for (String groupName : groupNamesForHelper) { - try { - createHelperCallable(groupName).call(); - } catch (Exception e) { - Debug.logError(e, MODULE); - } - } - } - return null; - })); ExecutionPool.getAllFutures(futures); // NOTE: doing some things before the ECAs and such to make sure it is in place just in case it is used in a service engine startup thing or