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?
below
RmiClientClassLoader rmiClassLoader = new RmiClientClassLoader(null,desc);
add Thread.currentThread().setContextClassLoader(rcl);
is ok now.