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]); + } }