如何使用http客户端调用rmi接口?

时间:2013-12-20 03:31:53

标签: java http system rmi legacy

现在许多传统系统都提供rmi或http接口来提供服务。 但我们的新系统只能提出http请求。 我想设计一个http-to-rmi模块。它由新系统调用,它对遗留系统进行rmi调用。 我还提供了一个功能来定义遗留系统的rmi接口并上传他们的rmi客户端。 这是我的设计:

public class RmiInterfaceDescription {
    private String rmiId;

    private String jarFile;

    private String rmiUrl;
    private String methodName ;
    private String interfaceName ;

    private List<String> paraClasses;
    private String returnClass;
....some gets and sets
}



public class RmiProxy {
    RmiDescriptionDao dao = new RmiDescriptionImpl();

    public String call(String rmiId, String json) throws Exception{
                //in the dao:desc.setJarFile("d:\\test.jar");
        RmiInterfaceDescription desc = dao.getDescriptionById(rmiId);


        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 {
    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;

    }
}

如果我不使用用户定义的类加载器(将rmi客户端放在类路径中),它可以工作。但是rmi客户端是动态上传到系统的,所以我使用classloader加载rmi客户端。 然后我再次运行它,它说:

Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
    java.lang.ClassNotFoundException: test.Hello (no security manager: RMI class loader disabled)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Unknown Source)
    at com.xxx.rmiproxy.RmiProxy.call(RmiProxy.java:40)
    at com.xxx.rmiproxy.RmiProxy.main(RmiProxy.java:18)
Caused by: java.lang.ClassNotFoundException: test.Hello (no security manager: RMI class loader disabled)
    at sun.rmi.server.LoaderHandler.loadProxyClass(Unknown Source)
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(Unknown Source)
    at java.rmi.server.RMIClassLoader.loadProxyClass(Unknown Source)
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(Unknown Source)
    at java.io.ObjectInputStream.readProxyDesc(Unknown Source)
之前我问过这个例外。有些人说可能代码库功能是我想要的。但我不知道如何使用这个功能。有人可以提出一些建议吗?

1 个答案:

答案 0 :(得分:0)

下面
        RmiClientClassLoader rmiClassLoader = new RmiClientClassLoader(null,desc);

添加     Thread.currentThread()setContextClassLoader(RCL);

现在还可以。