GWT服务器端反射

时间:2010-07-07 23:55:49

标签: java reflection gwt

我试图仅在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%的服务器代码,但我认为它可能是序列化的问题,但我也没有任何运气。

提前感谢任何人都可以给我的帮助。

4 个答案:

答案 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类