2013-12-20 72 views
0

現在很多傳統系統都提供rmi或http接口來提供服務。 但我們的新系統只能提出http請求。 我想設計一個http-to-rmi調制解調器,它被新系統調用,它使rmi調用遺留系統。 我還提供了一個功能來定義遺留系統的rmi接口並上傳他們的rmi客戶端。 這裏是我的設計:如何使用http客戶端調用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) 

我問過例外。有些人說可能codebase功能是我想要的,但我不知道如何使用此功能。有人可以提出一些建議嗎?

+0

'有些人'是對的。您必須使用代碼庫功能。 – EJP

+0

如何使用代碼庫功能?我可以在哪裏找到相關文檔? – user2219372

+0

我添加: System.setProperty(「java.rmi.server.codebase」,「file:/// d:\\ test.jar」); 仍然錯誤: 引起:java.lang.ClassNotFoundException:test.Hello(沒有安全管理器:禁用RMI類加載器) – user2219372

回答

0

低於
RmiClientClassLoader rmiClassLoader = new RmiClientClassLoader(null,desc); ().clip.currentThread()。setContextClassLoader(rcl);();}};}}}}}}}}}}}}}}

現在好了。