我试图仅在GWT应用程序的服务器端使用Reflection。我有一个基于非GWT示例的基本示例,可以在下面看到。
package com.xyz.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class EntryPoint {
/**
* @param args
*/
public static void main(String[] args) {
ClassLoader dynClassLoader = ClassLoader.getSystemClassLoader();
Class<?> dynClass = null;
try {
dynClass = dynClassLoader.loadClass("com.xyz.reflection.RunMe");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object dynInstance = null;
try {
dynInstance = dynClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Method dynMethod = null;
try {
try {
dynMethod = dynInstance.getClass().getMethod("returnSid",
new Class[] { PassMe.class });
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
String returnValue = (String) dynMethod.invoke(dynInstance,
new Object[] { new PassMe() });
System.out.println("Return Value: " + returnValue.toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
使用恰当名称:
package com.xyz.reflection;
public class PassMe {
private String sid = "DEFAULT_SID";
public PassMe() {
this.sid = "INITIATED_SID";
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
}
和
package com.xyz.reflection;
public class RunMe {
public String returnSid(PassMe s) {
return s.getSid();
}
}
这很好。当我尝试从GWT服务器端类运行它时,它不起作用,而是返回
java.lang.NoSuchMethodException: com.xyz.reflection.RunMe.returnSid(com.xyz.reflection.PassMe)
如果我将参数更改为String(而不是'PassMe'类),它可以正常工作。为什么不喜欢通过我的'PassMe'课程?尽管是100%的服务器代码,但我认为它可能是序列化的问题,但我也没有任何运气。
提前感谢任何人都可以给我的帮助。
答案 0 :(得分:1)
我认为这可能与类加载有关 - 但这只是一种预感,因为我无法在类似于你的上下文中进行实验。
以下是一些尝试的建议:
您使用:
ClassLoader dynClassLoader = ClassLoader.getSystemClassLoader();
dynClass = dynClassLoader.loadClass("com.xyz.reflection.RunMe");
加载RunMe类。
但是要加载PassMe类,请使用:
PassMe.class
尝试通过dynClassLoader加载PassMe类,并在getMethod()而不是PassMe.class中使用该实例。
我想知道,你需要使用dynClassLoader吗?
答案 1 :(得分:1)
除了finrod的解决方案,您还可以将类加载器更改为:
ClassLoader dynClassLoader = PassMe.class.getClassLoader();
您可以再次使用PassMe.class样式查找。用于查找加载器的类似乎并不重要。只是不是系统加载器。
奇怪的东西。我不怀疑GWT是否正在使用类加载器做一些奇怪的事情。
编辑:是的。 GWT在开发模式下将系统类加载器设置为com.google.appengine.tools.development.IsolatedAppClassLoader
。
答案 2 :(得分:0)
这在黑暗中几乎是一个镜头,但如果你更换它会有所帮助
dynMethod = dynInstance.getClass().getMethod("returnSid",
new Class[] { PassMe.class });
带
dynMethod = dynInstance.getClass().getMethod("returnSid", PassMe.class );
?
它在GWT服务器之外没有什么区别,但它可能以不同方式运用容器的VM。
答案 3 :(得分:0)
您是否将反射文件放在服务器端包中?
例如:
org.myproject.client - 你的gwt客户端软件包(把你的java文件放在这里,可以编译成java脚本NO REFLECTION)
org.myproject.server - 这里放任何包含反射的java文件
org.myproject.shared - 放在这里可以编译成java脚本的java类