I fixed this in revision 1480407.

It is very important that all developers understand that the recent changes to the entity engine are intended to improve thread safety - and they should not be short-circuited or defeated!

In this case, a form widget was trying to modify GenericValue instances that were retrieved from the cache. So, we have a situation where rendering code is changing the state of objects that should not be changed.

If you see any more exceptions like the one Jacques found, PLEASE fix the exception properly - copy the immutable GenericEntity instance to a Map that can be modified.

-Adrian

On 5/8/2013 11:04 AM, Jacques Le Roux wrote:
I just noticed at 
https://demo-trunk.ofbiz.apache.org/catalog/control/FindProductStore

that we have an issue with this line
this.resetBshInterpreter(localContext);

That we find twice in ModelForm.java.

 From stack trace it could related to immutable being introduced in the entity 
engine recently

---- cause ---------------------------------------------------------------------
Exception: java.lang.UnsupportedOperationException
Message: null
---- stack trace ---------------------------------------------------------------
java.lang.UnsupportedOperationException
java.util.Collections$UnmodifiableMap.remove(Collections.java:1288)
org.ofbiz.entity.GenericEntity.remove(GenericEntity.java:1451)
org.ofbiz.base.util.collections.MapContext.remove(MapContext.java:255)
org.ofbiz.widget.form.ModelForm.resetBshInterpreter(ModelForm.java:2139)


I used this

Index: framework/entity/src/org/ofbiz/entity/GenericEntity.java
===================================================================
--- framework/entity/src/org/ofbiz/entity/GenericEntity.java (revision 1480164)
+++ framework/entity/src/org/ofbiz/entity/GenericEntity.java (working copy)
@@ -314,6 +314,13 @@
          }
      }
+ public void setMutable() {
+        if (!this.mutable) {
+            this.mutable = true;
+            this.fields = new HashMap<String, Object>(this.fields);
+        }
+    }
+
      /**
       * @return Returns the isFromEntitySync.
       */
@@ -1448,7 +1455,10 @@
      // ---- Methods added to implement the Map interface: ----
public Object remove(Object key) {
-        return this.fields.remove(key);
+        setMutable();
+        this.fields.remove(key);
+        setImmutable();
+        return this.fields;
      }
public boolean containsKey(Object key) {


I can commit if you are ok with it

Jacques

Reply via email to