You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2018/01/08 15:04:04 UTC

svn commit: r1820568 - in /commons/proper/jexl/trunk: RELEASE-NOTES.txt src/main/java/org/apache/commons/jexl3/internal/Operators.java src/site/xdoc/changes.xml src/test/java/org/apache/commons/jexl3/IssuesTest200.java

Author: henrib
Date: Mon Jan  8 15:04:04 2018
New Revision: 1820568

URL: http://svn.apache.org/viewvc?rev=1820568&view=rev
Log:
JEXL-246:
Better error handling or operator overload error, added specific test, changes & release notes updated

Modified:
    commons/proper/jexl/trunk/RELEASE-NOTES.txt
    commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java
    commons/proper/jexl/trunk/src/site/xdoc/changes.xml
    commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java

Modified: commons/proper/jexl/trunk/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/RELEASE-NOTES.txt?rev=1820568&r1=1820567&r2=1820568&view=diff
==============================================================================
--- commons/proper/jexl/trunk/RELEASE-NOTES.txt (original)
+++ commons/proper/jexl/trunk/RELEASE-NOTES.txt Mon Jan  8 15:04:04 2018
@@ -40,6 +40,7 @@ New Features in 3.2:
 Bugs Fixed in 3.2:
 ==================
 
+* JEXL-246:      Intermittent ambiguous method invocation when processing assignOverload
 * JEXL-245:      Engine in strict mode fails to fail on unsolvable variables or properties
 * JEXL-244:      Webapp classloader memory leaks
 * JEXL-241:      NPE when script containing string interpolation executed in multiple threads

Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java?rev=1820568&r1=1820567&r2=1820568&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java Mon Jan  8 15:04:04 2018
@@ -139,26 +139,32 @@ public class Operators {
             }
         }
         // base eval
-        switch (operator) {
-            case SELF_ADD:
-                return arithmetic.add(args[0], args[1]);
-            case SELF_SUBTRACT:
-                return arithmetic.subtract(args[0], args[1]);
-            case SELF_MULTIPLY:
-                return arithmetic.multiply(args[0], args[1]);
-            case SELF_DIVIDE:
-                return arithmetic.divide(args[0], args[1]);
-            case SELF_MOD:
-                return arithmetic.mod(args[0], args[1]);
-            case SELF_AND:
-                return arithmetic.and(args[0], args[1]);
-            case SELF_OR:
-                return arithmetic.or(args[0], args[1]);
-            case SELF_XOR:
-                return arithmetic.xor(args[0], args[1]);
-            default:
-                throw new JexlException.Operator(node, operator.getOperatorSymbol(), null);
+        try {
+            switch (operator) {
+                case SELF_ADD:
+                    return arithmetic.add(args[0], args[1]);
+                case SELF_SUBTRACT:
+                    return arithmetic.subtract(args[0], args[1]);
+                case SELF_MULTIPLY:
+                    return arithmetic.multiply(args[0], args[1]);
+                case SELF_DIVIDE:
+                    return arithmetic.divide(args[0], args[1]);
+                case SELF_MOD:
+                    return arithmetic.mod(args[0], args[1]);
+                case SELF_AND:
+                    return arithmetic.and(args[0], args[1]);
+                case SELF_OR:
+                    return arithmetic.or(args[0], args[1]);
+                case SELF_XOR:
+                    return arithmetic.xor(args[0], args[1]);
+                default:
+                    // unexpected, new operator added?
+                    throw new UnsupportedOperationException(operator.getOperatorSymbol());
+            }
+        } catch (Exception xany) {
+            interpreter.operatorError(node, base, xany);
         }
+        return JexlEngine.TRY_FAILED;
     }
 
     /**

Modified: commons/proper/jexl/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/site/xdoc/changes.xml?rev=1820568&r1=1820567&r2=1820568&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/jexl/trunk/src/site/xdoc/changes.xml Mon Jan  8 15:04:04 2018
@@ -26,6 +26,9 @@
     </properties>
     <body>
         <release version="3.2" date="unreleased">
+            <action dev="henrib" type="fix" issue="JEXL-246" due-to="Dmitri Blinov">
+                Intermittent ambiguous method invocation when processing assignOverload
+            </action>
             <action dev="henrib" type="fix" issue="JEXL-245" due-to="Ate Douma">
                 Engine in strict mode fails to fail on unsolvable variables or properties
             </action>

Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java?rev=1820568&r1=1820567&r2=1820568&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java Mon Jan  8 15:04:04 2018
@@ -16,7 +16,8 @@
  */
 package org.apache.commons.jexl3;
 
-import java.text.NumberFormat;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
@@ -27,6 +28,10 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.logging.Level;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -264,8 +269,7 @@ public class IssuesTest200 extends JexlT
         m2.put("item", "B");
 
         handle(pool, script, m1);
-        System.out.println(script.execute(new MapContext(m2)));
-        System.out.println("Reached the end");
+        script.execute(new MapContext(m2));
         pool.shutdown();
     }
 
@@ -343,4 +347,71 @@ public class IssuesTest200 extends JexlT
             }
         }
     }
+
+    /**
+     * An arithmetic that implements 2 selfAdd methods.
+     */
+    public static class Arithmetic246 extends JexlArithmetic {
+        public Arithmetic246(boolean astrict) {
+            super(astrict);
+        }
+
+        public Collection<String> selfAdd(Collection<String> c, String item) {
+            c.add(item);
+            return c;
+        }
+
+        public Appendable selfAdd(Appendable c, String item) throws IOException {
+            c.append(item);
+            return c;
+        }
+    }
+
+    @Test
+    public void test246() throws Exception {
+        Log log246 = LogFactory.getLog(IssuesTest200.class);
+        // quiesce the logger
+        java.util.logging.Logger ll246 = java.util.logging.LogManager.getLogManager().getLogger(IssuesTest200.class.getName());
+        ll246.setLevel(Level.SEVERE);
+        JexlEngine jexl = new JexlBuilder().arithmetic(new Arithmetic246(true)).debug(true).logger(log246).create();
+        JexlScript script = jexl.createScript("z += x", "x");
+        MapContext ctx = new MapContext();
+        List<String> z = new ArrayList<String>(1);
+        Object zz;
+
+        // no ambiguous, std case
+        ctx.set("z", z);
+        zz = script.execute(ctx, "42");
+        Assert.assertTrue(zz == z);
+        Assert.assertEquals(1, z.size());
+        z.clear();
+        ctx.clear();
+
+        // method discovery will fail due to ambiguity: first arg is null, no type, 2 potential methods
+        // create a cache-miss entry in method resolution
+        String expectNullOperand = null;
+        try {
+            script.execute(ctx, "42");
+            Assert.fail("null z evaluating 'z += x'");
+        } catch(JexlException xae) {
+            expectNullOperand = xae.toString();
+        }
+        Assert.assertNotNull(expectNullOperand);
+
+        // second call will not provoque ambiguity (since cache-miss is recalled) but operator will fail nevertheless
+        try {
+            // discovery will fail for null arg
+            script.execute(ctx, "42");
+            Assert.fail("null z evaluating 'z += x'");
+        } catch(JexlException xae) {
+            expectNullOperand = xae.toString();
+        }
+        Assert.assertNotNull(expectNullOperand);
+
+        // a non ambiguous call still succeeds
+        ctx.set("z", z);
+        zz = script.execute(ctx, "42");
+        Assert.assertTrue(zz == z);
+        Assert.assertEquals(1, z.size());
+    }
 }