2011-05-24 95 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