简体   繁体   中英

GWT Server-side reflection

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");
    } 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.

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?

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.

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:
- your gwt client package (put here your java files that are able to be complied into java script NO REFLECTION) - 你的gwt客户端包(把你的java文件放在这里,可以编译成java脚本NO REFLECTION)
- put here any java files including reflection - 这里放任何包含反射的java文件
- put here java classes that are able to be compiled into java script - 放在这里可以编译成java脚本的java类

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM