I am trying to use Reflection on the server side only of a GWT app. I have a basic example working in a non-GWT example which can be seen below.
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");开发者_StackOverflow社区
} 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();
}
}
}
using the aptly named:
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;
}
}
and:
package com.xyz.reflection;
public class RunMe {
public String returnSid(PassMe s) {
return s.getSid();
}
}
This runs fine. When I try running this from a GWT server side class it doesn't work, and instead returns
java.lang.NoSuchMethodException: com.xyz.reflection.RunMe.returnSid(com.xyz.reflection.PassMe)
If I change the parameter to a String (instead of the 'PassMe' class) it works fine. Why does it not like passing my 'PassMe' class? I thought it might be an issue with serialization despite being 100% server code, but I haven't had any luck with this either.
Thanks in advance for any help anyone can give me with this.
In addition to finrod's solution, you can also change your class loader to something like:
ClassLoader dynClassLoader = PassMe.class.getClassLoader();
And you can use the PassMe.class style lookup again. The class used to find a loader doesn't seem to matter though. Just not the system loader.
Weird stuff. I wouldn't doubt if GWT is doing something weird with the class loader though.
Edit: Yep. GWT sets the system class loader to com.google.appengine.tools.development.IsolatedAppClassLoader
in dev mode.
I think this could be related to Class loading - but it is just a hunch as I cannot experiment with it in context similar to yours.
Here are some suggestions to try:
You use:
ClassLoader dynClassLoader = ClassLoader.getSystemClassLoader();
dynClass = dynClassLoader.loadClass("com.xyz.reflection.RunMe");
To load the RunMe Class.
However to load the PassMe class you use:
PassMe.class
Try to load the PassMe Class through the dynClassLoader and use that instance in the getMethod() instead of the PassMe.class.
I wonder, do you need to use the dynClassLoader?
This is pretty much a shot in the dark, but does it help if you replace
dynMethod = dynInstance.getClass().getMethod("returnSid",
new Class[] { PassMe.class });
with
dynMethod = dynInstance.getClass().getMethod("returnSid", PassMe.class );
?
It doesn't make a difference outside of a GWT server, but it may exercise the container's VM differently.
Did you put your reflection file in the server side package?
For example:
org.myproject.client - your gwt client package (put here your java files that are able to be complied into java script NO REFLECTION)
org.myproject.server - put here any java files including reflection
org.myproject.shared - put here java classes that are able to be compiled into java script
精彩评论