为什么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 上部署完全相同的MyInterface
servlet,即使是公开的。
万一它是相关的,我在 Eclipse Juno 中使用谷歌插件,我只在本地部署。
最后一件事:我检查了 的输出,proxy.getClass().getDeclaredMethods()
它确实包含getValue
. 但是,我不能自己简单地解析 bean 属性,因为我需要它在 EL 中工作,它依赖于Introspector
.
我真的被这个难住了,所以非常感谢任何指导。