Author: henrib
Date: Tue Dec  2 16:15:35 2014
New Revision: 1642927

URL: http://svn.apache.org/r1642927
Log:
Depending on unkown conditions, overriden varargs method may return false to 
isVarArgs;
Fix by checking method in declaring class hierarchy (MethodKey.isVarArgs).

Modified:
    commons/proper/jexl/trunk/pom.xml
    
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
    
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java
    commons/proper/jexl/trunk/src/site/xdoc/changes.xml
    
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java
    
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java

Modified: commons/proper/jexl/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/pom.xml?rev=1642927&r1=1642926&r2=1642927&view=diff
==============================================================================
--- commons/proper/jexl/trunk/pom.xml (original)
+++ commons/proper/jexl/trunk/pom.xml Tue Dec  2 16:15:35 2014
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-parent</artifactId>
-        <version>25</version>
+        <version>30</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.apache.commons</groupId>
@@ -100,9 +100,9 @@
 
     <dependencies>
         <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>1.1.3</version>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
         </dependency>
         <dependency>
             <groupId>junit</groupId>
@@ -208,6 +208,7 @@
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-scm-publish-plugin</artifactId>
+            <version>1.0-beta-2</version>
             <configuration>
               <ignorePathsToDelete>
                 <ignorePathToDelete>javadocs</ignorePathToDelete>

Modified: 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java?rev=1642927&r1=1642926&r2=1642927&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
 (original)
+++ 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
 Tue Dec  2 16:15:35 2014
@@ -217,31 +217,40 @@ public final class MethodKey {
     }
 
     /**
-     * Checks whether a method is accepts a variable number of arguments.
+     * Checks whether a method accepts a variable number of arguments.
      * <p>May be due to a subtle bug in some JVMs, if a varargs method is an 
override, depending on (may be) the
      * class introspection order, the isVarargs flag on the method itself will 
be false.
-     * To circumvent the potential problem, fetch the method with the same 
signature from iniial method declaring class,
-     * - which will be different if overriden  -and get the varargs flag from 
it.
+     * To circumvent the potential problem, fetch the method with the same 
signature from the super-classes,
+     * - which will be different if override  -and get the varargs flag from 
it.
      * @param method the method to check for varargs
      * @return true if declared varargs, false otherwise
      */
-    public static boolean isVarArgs(Method method) {
+    public static boolean isVarArgs(final Method method) {
         if (method == null) {
             return false;
         }
         if (method.isVarArgs()) {
             return true;
         }
+        // before climbing up the hierarchy, verify that the last parameter is 
an array
+        final Class<?>[] ptypes = method.getParameterTypes();
+        if (ptypes.length > 0 && ptypes[ptypes.length - 1].getComponentType() 
== null) {
+            return false;
+        }
+        final String mname = method.getName();
         // if this is an override, was it actually declared as varargs?
         Class<?> clazz = method.getDeclaringClass();
-        try {
-            Method m = clazz.getMethod(method.getName(), 
method.getParameterTypes());
-            if (m.isVarArgs()) {
-                return true;
+        do {
+            try {
+                Method m = clazz.getMethod(mname, ptypes);
+                if (m.isVarArgs()) {
+                    return true;
+                }
+            } catch (NoSuchMethodException xignore) {
+                // this should not happen...
             }
-        } catch (NoSuchMethodException xignore) {
-            // this should not happen...
-        }
+            clazz = clazz.getSuperclass();
+        } while(clazz != null);
         return false;
     }
 

Modified: 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java?rev=1642927&r1=1642926&r2=1642927&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java
 (original)
+++ 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java
 Tue Dec  2 16:15:35 2014
@@ -42,8 +42,8 @@ public interface JexlMethod {
      * Attempts to reuse this JexlMethod, checking that it is compatible with
      * the actual set of arguments.
      * Related to isCacheable since this method is often used with cached 
JexlMethod instances.
-     * @param obj the object to invoke the method upon
      * @param name the method name
+     * @param obj the object to invoke the method upon
      * @param params the method arguments
      * @return the result of the method invocation that should be checked by 
tryFailed to determine if it succeeded
      * or 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=1642927&r1=1642926&r2=1642927&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/jexl/trunk/src/site/xdoc/changes.xml Tue Dec  2 16:15:35 2014
@@ -26,6 +26,13 @@
     </properties>
     <body>
         <release version="3.0.1" date="unreleased">
+            <action dev="henrib" type="fix" >
+                Depending on unkown conditions, overriden varargs method may 
return false to isVarArgs;
+                fix by checking method in declaring class hierarchy.
+            </action>
+            <action dev="henrib" type="fix">
+                Performance problem in Interpreter.unknownVariable mechanism
+            </action>
             <action dev="henrib" type="fix" issue="JEXL-146" due-to="David 
Maplesden">
                 Performance problem in Interpreter.unknownVariable mechanism
             </action>

Modified: 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java?rev=1642927&r1=1642926&r2=1642927&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java
 (original)
+++ 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java
 Tue Dec  2 16:15:35 2014
@@ -194,4 +194,31 @@ public class ClassCreatorTest extends Je
         }
     }
 
+    public static class TwoCtors {
+        int value;
+
+        public TwoCtors(int v) {
+            this.value = v;
+        }
+
+        public TwoCtors(Number x) {
+            this.value = -x.intValue();
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
+    public void testBasicCtor() throws Exception {
+        JexlScript s = jexl.createScript("(c, v)->{ var ct2 = new(c, v); 
ct2.value; }");
+        Object r = s.execute(null, TwoCtors.class, 10);
+        assertEquals(10, r);
+        r = s.execute(null, TwoCtors.class, 5 + 5);
+        assertEquals(10, r);
+        r = s.execute(null, TwoCtors.class, 10d);
+        assertEquals(-10, r);
+        r = s.execute(null, TwoCtors.class, 100f);
+        assertEquals(-100, r);
+    }
 }

Modified: 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java?rev=1642927&r1=1642926&r2=1642927&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java
 (original)
+++ 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java
 Tue Dec  2 16:15:35 2014
@@ -1069,4 +1069,22 @@ public class IssuesTest extends JexlTest
         }
         assertNull("The arr2 property value should remain as null, not an 
empty array.", quux.arr2);
     }
+
+    public void test147() throws Exception {
+        JexlEngine JEXL = new Engine();
+        JexlContext jc = new MapContext();
+        JexlExpression e147 = JEXL.createExpression("quux = [one, two]");
+
+        jc.set("one", 1);
+        jc.set("two", 2);
+        int[] o1 = (int[])e147.evaluate(jc);
+        assertEquals(1, o1[0]);
+        assertEquals(2, o1[1]);
+
+        jc.set("one", 10);
+        jc.set("two", 20);
+        int[] o2 = (int[]) e147.evaluate(jc);
+        assertEquals(10, o2[0]);
+        assertEquals(20, o2[1]);
+    }
 }


Reply via email to