Whoever thought of <bean:page>, I love it, but it exposes some weird
introspection inconsistencies in the Tomcat container, and I am out of
my depth.  Help.

I have seen two classes that get thrown up as HttpServletRequests to the
container.

org.apache.catalina.connector.HttpRequestFacade
org.apache.catalina.core.ApplicationHttpRequest

I assume that these objects should be interchangeable, handed to the
servlet as an HttpServletRequest, treated as an HttpServletRequest.
All I know is that they behave differently from an introspection point
of view--end result being that when you have an
org.apache.catalina.connector.HttpRequestFacade, you can introspect its
get() methods, when you have an
org.apache.catalina.core.ApplicationHttpRequest, you can't.

My environment is Tomcat 4.0.1 running embedded in Jboss.

1.  I get handed a org.apache.catalina.connector.HttpRequestFacade as my
ServletRequest Object.toString().
2.  I expose it as a bean, <bean:page> and attempt to get the
servletPath property (in other words force a call to
HttpServletRequest.getServletPath()).
3.  This works, as shown below by my ridiculous log-hacking of
PropertyUtils:

[INFO,Default] Matched propertydescriptor to property: servletPath
[INFO,Default] In getReadMethod with PropertyDescriptor servletPath
looking for ReadMethod getServletPath
[INFO,Default] In getAccessibleMethod with method getServletPath
[INFO,Default] org.apache.catalina.connector.HttpRequestFacade is
public.  Cool.

At this point, we got the method and called it, got the property, yadda
yadda.

Let's try that again when our request happens to be a
org.apache.catalina.core.ApplicationHttpRequest:

[INFO,Default] Matched propertydescriptor to property: servletPath
[INFO,Default] In getReadMethod with PropertyDescriptor servletPath
looking for ReadMethod getServletPath
[INFO,Default] In getAccessibleMethod with method getServletPath
[INFO,Default] Didn't succeed elsewhere with getServletPath so let's
check interfaces.
[INFO,Default] In getAccessibleMethodFromInterfaceNest with class
org.apache.catalina.core.ApplicationHttpRequest method getServletPath
parameterTypes: length=0
[INFO,Default] Found 0 interfaces of
org.apache.catalina.core.ApplicationHttpRequest

[ERROR,EmbeddedCatalinaServiceSX] ApplicationDispatcher[/evangeline]
Servlet.service() for servlet jsp threw exception
javax.servlet.ServletException: No getter method for property
servletPath of bean httpservletreq
        at
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContex
tImpl.java:457)
        at org.apache.jsp.navbar$jsp._jspService(navbar$jsp.java:626)
        at
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:107)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at
org.apache.jasper.servlet.JspServlet$JspServletWrapper.service(JspServle
t.java:202)
          ...and fifteen more pages of stacktrace.

Basically what is happening is 
A) org.apache.catalina.core.ApplicationHttpRequest is not public, so we
can't use the method
B) For reasons not fully understood, the
getAccessibleMethodFromInterfaceNest can't find any interfaces for
org.apache.catalina.core.ApplicationHttpRequest.  

For a little background, org.apache.catalina.core.ApplicationHttpRequest
extends javax.servlet.http.HttpServletRequestWrapper, which implements
javax.servlet.http.HttpServletRequest, javax.servlet.ServletRequest.
I can't remember if when your superclass implements something, you do
too.

Anyway:  Is this a problem with the PropertyUtils?  Is this an issue
with the ApplicationHttpRequest implementation?  I don't know.  Please
advise.

For reference, my println'ed-up getAccessibleMethod and
getAccessibleMethodFromInterfaceNest are here:

private static Method getAccessibleMethod(Method method) {
        System.out.println("In getAccessibleMethod with method " +
method.getName());
        // Make sure we have a method to check
        if (method == null) {
            return (null);
        }

        // If the requested method is not public we cannot call it
        if (!Modifier.isPublic(method.getModifiers())) {
            System.out.println(method.getName() + " not public.
Bonking.");
            return (null);
        }

        // If the declaring class is public, we are done
        Class clazz = method.getDeclaringClass();
        if (Modifier.isPublic(clazz.getModifiers())) {
            System.out.println(method.getDeclaringClass().getName() + 
            " is public.  Cool.");
            return (method);
        }
        System.out.println("Didn't succeed elsewhere with " +
method.getName() + 
                           " so let's check interfaces.");
            
        // Check the implemented interfaces and subinterfaces
        String methodName = method.getName();
        Class[] parameterTypes = method.getParameterTypes();
        method =
            getAccessibleMethodFromInterfaceNest(clazz,
                                                 method.getName(),
 
method.getParameterTypes());
        return (method);
}

private static Method getAccessibleMethodFromInterfaceNest
        (Class clazz, String methodName, Class parameterTypes[]) {
        System.out.println("In getAccessibleMethodFromInterfaceNest with
class " +
                               clazz.getName() + "method " + methodName
+ 
                               " parameterTypes: length=" +
parameterTypes.length);
        for (int i = 0; i < parameterTypes.length;i++) {
            System.out.println(": " + parameterTypes[i].getName());
        }
            
        Method method = null;

        // Check the implemented interfaces of the parent class
        Class interfaces[] = clazz.getInterfaces();
        System.out.println("Found " + interfaces.length + " interfaces
of " +
                           clazz.getName());
        for (int i = 0; i < interfaces.length; i++) {
            System.out.println("Found interface: " +
interfaces[i].getName());
            // Is this interface public?
            if (!Modifier.isPublic(interfaces[i].getModifiers()))
                continue;

            // Does the method exist on this interface?
            try {
                method = interfaces[i].getDeclaredMethod(methodName,
 
parameterTypes);
            } catch (NoSuchMethodException e) {
                ;
            }
            if (method != null)
                break;

            // Recursively check our parent interfaces
            method =
                getAccessibleMethodFromInterfaceNest(interfaces[i],
                                                     methodName,
                                                     parameterTypes);
            if (method != null)
                break;

        }

        // Return whatever we have found
        if (method != null) System.out.println("Found method!");
        return (method);

    }






--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to