1

为什么Introspector不能正确发现 Jetty/GAE 中动态代理类的属性?

在使用 Jetty 在 GAE 上本地部署时,我在尝试使用 Java EL/JSP 的动态代理时遇到了这个奇怪的问题。您可以在此处查看原始问题。

无论如何,我已经简化了代码并缩小了问题范围。这是新代码:

MyServlet.java

package test;

// imports omitted

public class MyServlet extends HttpServlet {

    public interface MyInterface {
        public String getValue();
    }

    private static <T> T getProxy(Class<T> c) {
        return (T)Proxy.newProxyInstance(
                klass.getClassLoader(),
                new Class<?>[]{ klass },
                new InvocationHandler() {
                    @Override public Object invoke(Object proxy, Method m,
                            Object[] args) throws Throwable {
                        return null;
                    }
                });
    }

    public static void testIntrospection() {
        StringBuilder sb = new StringBuilder();
        try {
            MyInterface proxy = getProxy(MyInterface.class);
            BeanInfo info = Introspector.getBeanInfo(proxy.getClass());
            for (PropertyDescriptor d : info.getPropertyDescriptors())
                sb.append(d.getName()).append(", ");
        } catch (Exception e) {
            throw new AssertionError("failed", e);
        }
        throw new AssertionError("found: " + sb.toString());
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse resp) {
        testIntrospection();
    }

    public static void main(String... args) {
        testIntrospection();
    }
}

当我部署上面的代码并发送 GET 请求时,我得到以下信息:

java.lang.AssertionError: found: class,

但是,根据 Proxy的文档,我预计两者class都会value被发现。但是,当我运行它时,我得到了预期的输出。我还尝试将代理接口放在单独的文件/包中,但它不起作用。为了让事情变得更奇怪,当我更改为私有、受保护或默认时,我也会得到预期的输出。main()MyInterface

为什么我将问题限制在 GAE/Jetty?因为我能够毫无问题地在 Tomcat 7 上部署完全相同的MyInterfaceservlet,即使是公开的。

万一它是相关的,我在 Eclipse Juno 中使用谷歌插件,我只在本地部署。

最后一件事:我检查了 的输出,proxy.getClass().getDeclaredMethods()确实包含getValue. 但是,我不能自己简单地解析 bean 属性,因为我需要它在 EL 中工作,它依赖于Introspector.

我真的被这个难住了,所以非常感谢任何指导。

4

0 回答 0