Author: markt Date: Thu Jan 3 15:38:00 2013 New Revision: 1428403 URL: http://svn.apache.org/viewvc?rev=1428403&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54370 Improve handling of nulls when trying to match sets of parameters to a method in EL.
Added: tomcat/trunk/test/org/apache/el/util/ tomcat/trunk/test/org/apache/el/util/TestReflectionUtil.java (with props) tomcat/trunk/test/org/apache/el/util/Tester.java (with props) Modified: tomcat/trunk/java/org/apache/el/util/ReflectionUtil.java Modified: tomcat/trunk/java/org/apache/el/util/ReflectionUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/util/ReflectionUtil.java?rev=1428403&r1=1428402&r2=1428403&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/el/util/ReflectionUtil.java (original) +++ tomcat/trunk/java/org/apache/el/util/ReflectionUtil.java Thu Jan 3 15:38:00 2013 @@ -250,7 +250,6 @@ public class ReflectionUtil { return match; } - @SuppressWarnings("null") private static Method resolveAmbiguousMethod(Set<Method> candidates, Class<?>[] paramTypes) { // Identify which parameter isn't an exact match @@ -267,6 +266,11 @@ public class ReflectionUtil { } } + if (nonMatchClass == null) { + // Null will always be ambiguous + return null; + } + for (Method c : candidates) { if (c.getParameterTypes()[nonMatchIndex] == paramTypes[nonMatchIndex]) { @@ -294,6 +298,12 @@ public class ReflectionUtil { // src will always be an object private static boolean isAssignableFrom(Class<?> src, Class<?> target) { + // Short-cut. null is always assignable to an object and in EL null + // can always be coerced to a valid value for a primitive + if (src == null) { + return true; + } + Class<?> targetClass; if (target.isPrimitive()) { if (target == Boolean.TYPE) { @@ -334,7 +344,11 @@ public class ReflectionUtil { if (types != null) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < types.length; i++) { - sb.append(types[i].getName()).append(", "); + if (types[i] == null) { + sb.append("null, "); + } else { + sb.append(types[i].getName()).append(", "); + } } if (sb.length() > 2) { sb.setLength(sb.length() - 2); Added: tomcat/trunk/test/org/apache/el/util/TestReflectionUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/util/TestReflectionUtil.java?rev=1428403&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/el/util/TestReflectionUtil.java (added) +++ tomcat/trunk/test/org/apache/el/util/TestReflectionUtil.java Thu Jan 3 15:38:00 2013 @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.el.util; + +import javax.el.MethodNotFoundException; + +import org.junit.Test; + +public class TestReflectionUtil { + + private static final Tester BASE = new Tester(); + + /* + * Expect failure as it is not possible to identify which method named + * "testA()" is intended. + */ + @Test(expected=MethodNotFoundException.class) + public void testBug54370a() { + ReflectionUtil.getMethod(BASE, "testA", + new Class[] {null, String.class}, + new Object[] {null, ""}); + } + + /* + * Expect failure as it is not possible to identify which method named + * "testB()" is intended. Note: In EL null can always be coerced to a valid + * value for a primative. + */ + @Test(expected=MethodNotFoundException.class) + public void testBug54370b() { + ReflectionUtil.getMethod(BASE, "testB", + new Class[] {null, String.class}, + new Object[] {null, ""}); + } + + @Test + public void testBug54370c() { + ReflectionUtil.getMethod(BASE, "testC", + new Class[] {null}, + new Object[] {null}); + } + + @Test + public void testBug54370d() { + ReflectionUtil.getMethod(BASE, "testD", + new Class[] {null}, + new Object[] {null}); + } +} Propchange: tomcat/trunk/test/org/apache/el/util/TestReflectionUtil.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/test/org/apache/el/util/Tester.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/util/Tester.java?rev=1428403&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/el/util/Tester.java (added) +++ tomcat/trunk/test/org/apache/el/util/Tester.java Thu Jan 3 15:38:00 2013 @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.el.util; + +import java.io.InputStream; + +public class Tester { + + @SuppressWarnings("unused") + public void testA(InputStream param1, String param2) { + // NO-OP + } + + @SuppressWarnings("unused") + public void testA(Long param1, String param2) { + // NO-OP + } + + @SuppressWarnings("unused") + public void testB(InputStream param1, String param2) { + // NO-OP + } + + @SuppressWarnings("unused") + public void testB(long param1, String param2) { + // NO-OP + } + + @SuppressWarnings("unused") + public void testC(long param1) { + // NO-OP + } + + @SuppressWarnings("unused") + public void testD(String param1) { + // NO-OP + } +} Propchange: tomcat/trunk/test/org/apache/el/util/Tester.java ------------------------------------------------------------------------------ svn:executable = * --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org