This is an automated email from the ASF dual-hosted git repository.

mridulpathak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 46952dbe6 Take devreload's reader names from the reader caches
46952dbe6 is described below

commit 46952dbe675369cc3f3d89831fbeff698325be31
Author: Mridul Pathak <[email protected]>
AuthorDate: Sun Nov 1 13:29:19 2026 +0530

    Take devreload's reader names from the reader caches
    
    EntityModelReloader looked up the private modelName field of ModelReader 
and ModelGroupReader by reflection. That field was removed as unused on trunk, 
so the lookup failed and entity and entity-group hot-reload were disabled for 
the whole session. The reader names now come from the keys of each reader cache.
---
 devreload/README.md                                |  2 +-
 .../ofbiz/devreload/EntityModelReloader.java       | 42 ++++++++--------------
 2 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/devreload/README.md b/devreload/README.md
index 0cc872a3a..26d42bd4c 100644
--- a/devreload/README.md
+++ b/devreload/README.md
@@ -357,7 +357,7 @@ OFBiz.
 | `<attribute>`/`<override>` schema warning (`cvc-complex-type.2.4.a`) repeats 
on every reload cycle | `<attribute>` elements must come before `<override>` 
per `services.xsd` | Reorder the elements in the edited `services.xml` |
 | Log: "Hot-reload: failed to reload entity model '...' -- fix the entitydef 
XML and save again" | Invalid XML, or a view-entity referencing a non-existent 
member entity | Fix the reported error and save again — self-heals 
automatically, no restart needed even for a broken intermediate save. In the 
meantime, only the specifically-broken entity/view is unavailable (confirmed 
live) — every other already-working entity keeps responding normally |
 | An `entitydef` change isn't picked up at all | Either a brand-new file not 
yet declared via `entity-resource` in `ofbiz-component.xml` (needs a restart — 
same as a new component), or it's seed/demo data (`entity-resource 
type="data"`/`"data-security"`), which this plugin doesn't watch | Restart for 
a new resource declaration; seed data reload is a different, unaddressed 
concern |
-| Log: "could not resolve ModelReader's private fields 
(READERS/entityCache/modelName) via reflection" | This OFBiz version's 
`ModelReader` implementation changed in a way `EntityModelReloader`'s 
reflection didn't account for | Entity/view-entity hot-reload is disabled for 
the session (Java and services.xml hot-reload are unaffected); file an issue 
against `devreload` naming the OFBiz version |
+| Log: "could not resolve ModelReader's private fields (READERS/entityCache) 
via reflection" | This OFBiz version's `ModelReader` implementation changed in 
a way `EntityModelReloader`'s reflection didn't account for | 
Entity/view-entity hot-reload is disabled for the session (Java and 
services.xml hot-reload are unaffected); file an issue against `devreload` 
naming the OFBiz version |
 | New field/entity shows up in the reloaded model but queries against it fail 
(missing column/table) | The DB schema itself wasn't updated — entitydef reload 
only ever changes the in-memory model | Run webtools' "Update Database", or set 
`-Dofbiz.hotreload.autoUpdateSchema=true` (`-Photreload.autoUpdateSchema=true`) 
to have it happen automatically on every entitydef save |
 | Log: "schema auto-update failed for delegator '...'" | The datasource for 
that group/helper isn't reachable, or `checkDb` itself hit a DB-specific error 
| `checkDb` only ever adds — it's safe to fix the underlying DB issue and save 
again |
 | A `*Labels.xml` or `.properties` edit under `config/` isn't picked up | 
Either the file doesn't end in `Labels.xml` (e.g. a component using the older 
singular convention, if any), or it's one of the two static-snapshot exceptions 
(`debug.properties` log levels, `security.properties`'s 
`password.encrypt.pbkdf2.iterations`) | Rename to match the `Labels.xml` 
convention, or restart for the two named exceptions — every other property and 
label reloads live |
diff --git 
a/devreload/src/main/java/org/apache/ofbiz/devreload/EntityModelReloader.java 
b/devreload/src/main/java/org/apache/ofbiz/devreload/EntityModelReloader.java
index a676f8611..e0ea8f3bf 100644
--- 
a/devreload/src/main/java/org/apache/ofbiz/devreload/EntityModelReloader.java
+++ 
b/devreload/src/main/java/org/apache/ofbiz/devreload/EntityModelReloader.java
@@ -87,12 +87,10 @@ final class EntityModelReloader {
     private static volatile boolean entityReloadAvailable;
     private static Field modelReaderReadersField;
     private static Field modelReaderEntityCacheField;
-    private static Field modelReaderModelNameField;
 
     private static volatile boolean groupReloadAvailable;
     private static Field modelGroupReaderReadersField;
     private static Field modelGroupReaderGroupCacheField;
-    private static Field modelGroupReaderModelNameField;
 
     private static volatile boolean delegatorCacheClearAvailable;
     private static Field delegatorFactoryDelegatorsField;
@@ -135,8 +133,11 @@ final class EntityModelReloader {
         }
 
         boolean allSucceeded = true;
-        for (ModelReader reader : readers.values()) {
-            allSucceeded &= rebuildOneEntityReader(reader);
+        for (String readerName : readers.getCacheLineKeys()) {
+            ModelReader reader = readers.get(readerName);
+            if (reader != null) {
+                allSucceeded &= rebuildOneEntityReader(readerName, reader);
+            }
         }
         return allSucceeded;
     }
@@ -167,8 +168,11 @@ final class EntityModelReloader {
         }
 
         boolean allSucceeded = true;
-        for (ModelGroupReader reader : readers.values()) {
-            allSucceeded &= rebuildOneGroupReader(reader);
+        for (String readerName : readers.getCacheLineKeys()) {
+            ModelGroupReader reader = readers.get(readerName);
+            if (reader != null) {
+                allSucceeded &= rebuildOneGroupReader(readerName, reader);
+            }
         }
         return allSucceeded;
     }
@@ -406,8 +410,7 @@ final class EntityModelReloader {
     }
 
     /** Nulls {@code reader}'s {@code entityCache} field, then eagerly 
rebuilds it, self-healing on failure. */
-    private static boolean rebuildOneEntityReader(ModelReader reader) {
-        String readerName = readField(modelReaderModelNameField, reader);
+    private static boolean rebuildOneEntityReader(String readerName, 
ModelReader reader) {
         long start = System.currentTimeMillis();
         try {
             modelReaderEntityCacheField.set(reader, null);
@@ -427,8 +430,7 @@ final class EntityModelReloader {
     }
 
     /** Nulls {@code reader}'s {@code groupCache} field, then eagerly rebuilds 
it, self-healing on failure. */
-    private static boolean rebuildOneGroupReader(ModelGroupReader reader) {
-        String readerName = readField(modelGroupReaderModelNameField, reader);
+    private static boolean rebuildOneGroupReader(String readerName, 
ModelGroupReader reader) {
         String delegatorName = resolveDelegatorNameForGroupReader(readerName);
         if (delegatorName == null) {
             Debug.logWarning("Hot-reload: could not find a delegator whose 
entity-group-reader is '" + readerName
@@ -474,16 +476,6 @@ final class EntityModelReloader {
         return null;
     }
 
-    /** Best-effort read of a private {@code String} field, purely for log 
messages. */
-    private static String readField(Field field, Object target) {
-        try {
-            Object value = field.get(target);
-            return value != null ? value.toString() : "?";
-        } catch (ReflectiveOperationException e) {
-            return "?";
-        }
-    }
-
     /** Best-effort re-null of {@code field} on {@code target}, logging if 
even that fails. */
     private static void reNullQuietly(Field field, Object target, String 
fieldLabel, String readerName) {
         try {
@@ -521,12 +513,10 @@ final class EntityModelReloader {
                 modelReaderReadersField.setAccessible(true);
                 modelReaderEntityCacheField = 
ModelReader.class.getDeclaredField("entityCache");
                 modelReaderEntityCacheField.setAccessible(true);
-                modelReaderModelNameField = 
ModelReader.class.getDeclaredField("modelName");
-                modelReaderModelNameField.setAccessible(true);
                 entityReloadAvailable = true;
             } catch (ReflectiveOperationException | SecurityException e) {
-                Debug.logError(e, "Hot-reload: could not resolve ModelReader's 
private fields (READERS/entityCache"
-                        + "/modelName) via reflection -- this OFBiz version's 
ModelReader implementation may have "
+                Debug.logError(e, "Hot-reload: could not resolve ModelReader's 
private fields (READERS/entityCache)"
+                        + " via reflection -- this OFBiz version's ModelReader 
implementation may have "
                         + "changed. Entity/view-entity hot-reload is disabled 
for this session; Java and "
                         + "services.xml hot-reload are unaffected.", MODULE);
                 entityReloadAvailable = false;
@@ -537,12 +527,10 @@ final class EntityModelReloader {
                 modelGroupReaderReadersField.setAccessible(true);
                 modelGroupReaderGroupCacheField = 
ModelGroupReader.class.getDeclaredField("groupCache");
                 modelGroupReaderGroupCacheField.setAccessible(true);
-                modelGroupReaderModelNameField = 
ModelGroupReader.class.getDeclaredField("modelName");
-                modelGroupReaderModelNameField.setAccessible(true);
                 groupReloadAvailable = true;
             } catch (ReflectiveOperationException | SecurityException e) {
                 Debug.logError(e, "Hot-reload: could not resolve 
ModelGroupReader's private fields (READERS/"
-                        + "groupCache/modelName) via reflection -- this OFBiz 
version's ModelGroupReader "
+                        + "groupCache) via reflection -- this OFBiz version's 
ModelGroupReader "
                         + "implementation may have changed. entitygroup.xml 
hot-reload is disabled for this "
                         + "session; entity/view-entity hot-reload is 
unaffected.", MODULE);
                 groupReloadAvailable = false;

Reply via email to