2011-05-24 86 views
1

我目前正在開發一個通過rmi加載類的系統。該系統使用類加載器與服務器進行通信以獲取類。代碼如下。RMI UnmarshalException

服務器:

import rocks.squareRock; 

import java.rmi.Naming; 
import java.rmi.RemoteException; 
import java.rmi.server.UnicastRemoteObject; 

public class Server extends UnicastRemoteObject 
     implements RemInterface { 

    public Server() throws RemoteException { 
     super(); 
    } 

    public static void main(String argv[]) { 
     try { 
      Server serv = new Server(); 
      Naming.rebind("RockServer", serv); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 
    } 

    public Class<?> getRockClass(String type) { 
     if (type.equals("squareRock")) 
      return squareRock.class; 
     else 
      return null; 
    } 
} 

客戶:

import rocks.Rock; 

import java.net.MalformedURLException; 
import java.rmi.Naming; 
import java.rmi.NotBoundException; 
import java.rmi.RemoteException; 

public class Client { 
    RemInterface reminterface = null; 
    RockLoader rl = null; 

    public Client() { 
     String strName = "rmi://127.0.0.1/RockServer"; 
     try { 
      reminterface = (RemInterface) Naming.lookup(strName); 
      rl = new RockLoader(reminterface); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } catch (NotBoundException e) { 
      e.printStackTrace(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 

     loadRock("squareRock"); 

    } 

    public Rock loadRock(String rock) { 
     try { 
      return (Rock) rl.loadClass(rock, false).newInstance(); 
     } catch (Throwable t) { 
      return null; 
     } 
    } 
} 

接口:

public interface RemInterface { 
    public Class<?> getRockClass(String type) throws RemoteException; 
} 

RockLoader:

import java.io.Serializable; 

public class RockLoader extends ClassLoader implements Serializable { 

    private RemInterface reminterface = null; 

    public RockLoader(RemInterface reminterface) { 
     super(); 
     this.reminterface = reminterface; 
    } 

    @Override 
    protected synchronized Class<?> loadClass(String className, boolean resolve) 
      throws ClassNotFoundException { 
     try { 
      return reminterface.getRockClass(className); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

我這個得到的錯誤是(客戶端):

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.lang.ClassNotFoundException: SquareRock 

這混淆了我,因爲我不是解組SquareRock實例,但一類。我唯一的想法是,我的類加載器可能是錯誤的。

+0

[RMI ClassNotFoundException]的可能重複(http://stackoverflow.com/questions/6085064/rmi-classnotfoundexception) – EJP 2011-05-25 04:15:39

回答

1

無論它是一個Class還是一個對象都沒關係。除非您使用RMI代碼庫功能,否則接收JVM必須在其類路徑中包含該類。你正在做的是基本上試圖自己實現代碼庫功能。你不能那樣做。

+0

+1。傳輸的類對象只包含類名(也可能是代碼庫URI),而不是類的字節碼。我們可以實現一些方案,其中RMI流包含整個字節代碼並從中加載類,但是這需要在客戶端和服務器端進行合作(並且發送方的類加載器必須允許訪問活動類的字節代碼)。 – 2011-06-12 15:34:06

+0

你可以看看這個問題http://stackoverflow.com/questions/28520613/javaee-rmi-objects-security-issue? – 2015-02-15 16:14:06