Question

Now many legacy systems provide rmi or http interfaces to provide service . but our new system can make only http request. I want to design a http-to-rmi modue.It is called by new system and it make rmi calls to legacy system. I also provide a feature to define legacy system's rmi interface and upload their rmi client. here is my design:

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;

    }
}

it could works if i does not use user defined classloader (put the rmi client in the classpath).but the rmi client is upload to the system dynamicly ,so i use classloader to load the rmi client. and i run it again ,it says:

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)

i asked the exception before . some people said maybe codebase feature is what I want.but i don't know how to use this feature. Is anyone can give some suggestions?

Was it helpful?

Solution

below
RmiClientClassLoader rmiClassLoader = new RmiClientClassLoader(null,desc);

add Thread.currentThread().setContextClassLoader(rcl);

is ok now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top