提问者:小点点

无安全管理器:禁用RMI类加载器


我喜欢打电话给RMI,但是例外被限制了。它有什么问题?

线程"main"java. rmi.UnmarshalException中的异常:错误解组返回;嵌套异常是:java.lang.ClassNotFoundException:test.Hello(无安全管理器:禁用了RMI类加载器)at sun.rmi.在com.xx.rmiproxy.RmiProxy.main(RmiProxy.java:18)atcom.xx.rmiproxy.RmiProxy.call(RmiProxy.java:39)at java.lang.ClassNotFoundException:test.Hello(无安全管理器:禁用了RMI类加载器)at sun.rmi.server.LoaderHandler.loadProxyClass(未知源)at java.rmi.server.RMIClassLoader2 dolls.loadProxyClass(未知源)

public String call(String rmiId, String json) throws Exception{

    RmiInterfaceDescription desc = dao.getDescriptionById(rmiId);
    desc.setJarFile("d:\\test.jar");

    RmiClientClassLoader rmiClassLoader = new RmiClientClassLoader(null,desc);

    Class interfaceClass = rmiClassLoader.loadClass(desc.getInterfaceName());
    List<String> paraClasses = desc.getParaClasses();

    Class returnClass = rmiClassLoader.loadClass(desc.getReturnClass());

    Object obj = Naming.lookup(desc.getRmiUrl());

    Class[] parameterTypes = new Class[paraClasses.size()];

    for(int i=0;i<paraClasses.size();i++){
        parameterTypes[i]= rmiClassLoader.loadClass(paraClasses.get(i));
    }

    Method method = interfaceClass.getDeclaredMethod(desc.getMethodName(),
            parameterTypes);

    Object params[] = parseParamsFromJson();
    Object result = method.invoke(obj, "ssd");


    return encode(result);
}

.....

public class RmiClientClassLoader extends URLClassLoader {
public static void main(String args[]) throws Exception {
    RmiInterfaceDescription description = new RmiInterfaceDescription();

    description.setJarFile("d:\\test.jar");
    RmiClientClassLoader cl = new RmiClientClassLoader(null, description);

    Class clientClass = cl.loadClass("test.client.HelloClient");
}

private String basedir;
private RmiInterfaceDescription description;

@SuppressWarnings("deprecation")
public RmiClientClassLoader(String basedir,
        RmiInterfaceDescription description) throws MalformedURLException {
    super(new URL[] { new File(description.getJarFile()).toURL() });
    this.basedir = basedir;
    this.description = description;

}

共2个答案

匿名用户

您看错了。此异常的重要部分是ClassNotFoundException及其命名的类。需要在客户端部署的任何类,如果您将其作为单独的进程运行,则可供注册表使用。

我不知道你为什么要定义自己的类加载器。代码库功能通常就足够了。

匿名用户

如果您使用注册表查找,由于安全问题,客户端需要(远程)接口,其完整包名与存根处理程序类中定义的相同。只需将远程接口放在定义、客户端和服务器中相同的完整包名中。