You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2014/06/20 23:55:01 UTC

[Bug 56652] New: EL defineFunction does not support method signatures with arrays as arguments

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: dev@tomcat.apache.org
          Reporter: artfiedler@gmail.com

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: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 56652] EL defineFunction does not support method signatures with arrays as arguments

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56652

Mark Thomas <ma...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #3 from Mark Thomas <ma...@apache.org> ---
This has been fixed in 8.0.x for 8.0.10 onwards. I also added support for
varargs.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 56652] EL defineFunction does not support method signatures with arrays as arguments

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56652

Mark Thomas <ma...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 OS|                            |All

--- Comment #1 from Mark Thomas <ma...@apache.org> ---
Patches should be attached to issues in diff -u format. Providing the patch in
other formats slows down the review process.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 56652] EL defineFunction does not support method signatures with arrays as arguments

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56652

--- Comment #2 from Mark Thomas <ma...@apache.org> ---
The proposed solution can not be used. The EL API may not be changed. I'm
working on a solution along similar lines but the work is done in the
ELProcessor.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org