return currentMap.remove(key);

is the remove method call.

There is no point removing an element in a copy of the Map:

Map<K, V> currentMap = this.stackList.get(0);
try {
    return currentMap.remove(key);
} catch (UnsupportedOperationException e) {
    return (V) currentMap.get(key);
-OR-
    return null;
}

But that simply hides the problem. The code calling this method should do the 
try-catch.

You said the problem is in one of the screen widgets - so that is where it 
should be fixed. Why is a widget removing elements from a Map? So, there is a 
design flaw in there somewhere.

Just let me know where in the screen widget code you encountered the problem. I 
caused it, so I should fix it.

-Adrian

On 5/8/2013 3:10 PM, Jacques Le Roux wrote:
You mean that, right? It works but I'm unsure of the remove method call yuo 
talked about.

Index: framework/base/src/org/ofbiz/base/util/collections/MapContext.java
===================================================================
--- framework/base/src/org/ofbiz/base/util/collections/MapContext.java 
(revision 1480164)
+++ framework/base/src/org/ofbiz/base/util/collections/MapContext.java (working 
copy)
@@ -20,6 +20,7 @@
import java.util.Collection;
  import java.util.Collections;
+import java.util.HashMap;
  import java.util.List;
  import java.util.Locale;
  import java.util.Map;
@@ -251,8 +252,13 @@
       */
      public V remove(Object key) {
          // all write operations are local: only remove from the Map on the 
top of the stack
-        Map<K, V> currentMap = this.stackList.get(0);
-        return currentMap.remove(key);
+        Map<K, V> currentMap = this.stackList.get(0);
+        try {
+            return currentMap.remove(key);
+        } catch (UnsupportedOperationException e) {
+            Map<K, V> tempMap =  new HashMap<K, V>(currentMap);
+            return (V) tempMap.remove(key);
+        }
      }
Jacques


From: "Adrian Crum" <[email protected]>
Just use a try-catch block around the remove method call.

-Adrian

On 5/8/2013 12:30 PM, Jacques Le Roux wrote:
A solution could be to rather do the same at MapContext.remove() level
But then we need to know if the collection is immutable or not to reset it 
after change.
And it seems there are no reliable ways to know if a Java collection is 
immutable or not, even using reflection.
We could introduce Guava com.google.common.collect.ImmutableCollection or rely 
on UnsupportedOperationException exceptions

What do you think?

Jacques

From: "Adrian Crum" <[email protected]>
The GenericEntity instance was made immutable for a reason. Please do
not change its behavior.

-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