https://issues.apache.org/bugzilla/show_bug.cgi?id=56652
Bug ID: 56652
Summary: EL defineFunction does not support method signatures
with arrays as arguments
Product: Tomcat 8
Version: trunk
Hardware: PC
Status: NEW
Severity: normal
Priority: P2
Component: EL
Assignee: [email protected]
Reporter: [email protected]
When defineFuncton in ELProcessor is called it uses class.getName() to compare
class names, and the MethodSignature class used to parse the signatures will
return whatever value is defined(in the method signature) as the class name
when its fully qualified.
So if the method signature is lets say "boolean
sameSize(java.util.Collection[])" defineFunction wont find a matching method on
the provided class, because class.getName() will return
"[Ljava.util.Collection;" instead.
To get around this I made some tweaks to unqualified type's also to check for
array, and also to always get the correct class name, I changed it to always
get the referenced class then use the getName() function there.
I added most the functionality to the ImportHandler to reuse the cache and
because it was contently there
Original Code in 8.0.8
[javax.el.ELProcessor- MethodSignature]
ImportHandler importHandler = context.getImportHandler();
for (int i = 0; i < parameterTypeNames.length; i++) {
parameterTypeNames[i] = parameterTypeNames[i].trim();
if (!parameterTypeNames[i].contains(".")) {
Class<?> clazz = importHandler.resolveClass(
parameterTypeNames[i]);
if (clazz == null) {
throw new NoSuchMethodException(Util.message(
context,
"elProcessor.defineFunctionInvalidParameterTypeName",
parameterTypeNames[i], methodName,
className));
}
parameterTypeNames[i] = clazz.getName();
}
}
Replaced with:
ImportHandler importHandler = context.getImportHandler();
Class<?> clazz;
for (int i = 0; i < parameterTypeNames.length; i++) {
clazz = importHandler.extendedResolveClass(parameterTypeNames[i].trim());
if (clazz == null) {
throw new NoSuchMethodException(Util.message(
context,
"elProcessor.defineFunctionInvalidParameterTypeName",
parameterTypeNames[i], methodName,
className));
}
parameterTypeNames[i] = clazz.getName();
}
[javax.el.ImportHandler] - Added the following methods
/**
* This version of Class<?> resolveClass(String name) will allow qualified
names,
* handles arrays, and for qualified names will ignore requiring the type is a
public class
* Note: added to this class to take advantage of the existing cache, and will
cache
* original name for qualified names before parsing
* @param name Classname with or without namespace
* @return
*/
public java.lang.Class<?> extendedResolveClass(String name) {
Class<?> result = clazzes.get(name);
if (result == null) {
int firstBracketIndex = name.indexOf('[');
if (name.contains("."))
{
try {
if (firstBracketIndex > -1)
result = Class.forName(convertArrayClassName(name,
firstBracketIndex));
else
result = Class.forName(name);
} catch (ClassNotFoundException e) {
return null;
}
Class<?> conflict = clazzes.get(name);
if (conflict != null) {
throw new ELException(Util.message(null,
"importHandler.ambiguousImport", name,
conflict.getName()));
}
clazzes.put(name, result);
}
else {
// Search the package imports - note there may be multiple matches
// (which correctly triggers an error)
for (String p : packages) {
String className = p + '.' + name;
if (firstBracketIndex > -1)
className = convertArrayClassName(className,
firstBracketIndex);
result = findClass(className, true);
}
}
}
return result;
}
/**
* Converts a class name in the format of java.util.Collection[] to
[Ljava.util.Collection;
* @param typeName Original class name
* @param firstBracketIndex position of the first [
* @return The class name in the format of [LclassName;
*/
private String convertArrayClassName(String typeName, int firstBracketIndex)
{
final int length = typeName.length();
StringBuilder sb = new StringBuilder(length + 1); // +1 is to account for
';'
sb.append('[');
for(int i = firstBracketIndex + 2; i < length; i++)
{
if (typeName.charAt(i) == '[')
{
sb.append('[');
i++;
}
}
typeName = typeName.substring(0, firstBracketIndex).trim();
switch(typeName)
{
case "boolean":
sb.append('Z');
break;
case "byte":
sb.append('B');
break;
case "char":
sb.append('C');
break;
case "double":
sb.append('D');
break;
case "float":
sb.append('F');
break;
case "int":
sb.append('I');
break;
case "long":
sb.append('J');
break;
case "short":
sb.append('S');
break;
default:
sb.append('L');
sb.append(typeName);
sb.append(';');
break;
}
return sb.toString();
}
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]