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;