2011-08-24 67 views
0

我已经继承了一些Java RMI客户机/服务器代码,虽然它在一台机器上运行良好,但我一直无法获得它在我的开发环境中运行。Java RMI ServerException - java.lang.ClassNotFoundException:org.prog.rmi.RmiServer_Stub

问题是,当我使用以下java.exe -Djava.security.policy=conf\server.policy -SRC;. -Djava.library.path=. org.prog.rmi.RmiServer

我碰到下面的错误运行服务器:

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: org.prog.rmi.RmiServer_Stub (no security manager: RMI class loader disabled) 
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:396) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250) 
    at sun.rmi.transport.Transport$1.run(Transport.java:159) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) 
    ... 

server.policy文件

grant { 
    permission java.security.AllPermission; 
}; 

我的Java代码:

 package org.prog.rmi; 

     import java.rmi.Naming; 
     import java.rmi.RemoteException; 
     import java.rmi.RMISecurityManager; 
     import java.rmi.server.UnicastRemoteObject; 
     import java.rmi.registry.*; 

     public class RmiServer extends UnicastRemoteObject 
      implements RmiServerIntf { 

     private BatchApi bapi; 
     private String iniFileLocation; 
     private String layoutOption; 
     private int addressCount = 0; 
     private RefInt apiHandle = new RefInt(); 


     public RmiServer(String iniFileLocation,String layoutOption) throws RemoteException 
     { super(); 
      this.iniFileLocation = iniFileLocation; 
      this.layoutOption = layoutOption; 
      initAPI(); 
      startupAPI(); 
      openAPI();  
     } 

     public static void main(String args[]) 
     { 
      System.out.println("RMI server started"); 

      // Create and install a security manager 
      if (System.getSecurityManager() == null) 
      { 
       System.setSecurityManager(new RMISecurityManager()); 
       System.out.println("Security manager installed."); 
      } 
      else 
       System.out.println("Security manager already exists."); 

      try //special exception handler for registry creation 
      { 
       LocateRegistry.createRegistry(1099); 
       System.out.println("java RMI registry created."); 
      } 
      catch (RemoteException e) 
      { 
       //do nothing, error means registry already exists 
       System.out.println("java RMI registry already exists."); 
      } 

      try 
      { 
       //Instantiate RmiServer 
       for (String arg: args){ 
        System.out.println(arg); 
       } 

       RmiServer obj = new RmiServer(args[0],args[1]); 

       // Bind this object instance to the name "RmiServer" 
       Naming.rebind("//127.0.0.1/RmiServer", obj); 
       System.out.println("PeerServer bound in registry"); 

      } 
      catch (Exception e) 
      { 
       System.err.println("RMI server exception:"); 
       e.printStackTrace(); 
      } 
     }  
} 

我已经看到了有关的java.rmi.server.codebase解决方案,但没有任何运气设置此任

+0

不应该将服务器绑定到“rmi:// localhost:1099/RmiServer”吗?您的网址似乎没有正确书写。我不确定这是问题的原因,但修复这将是一个好的开始。 –

+0

这听起来很棘手,我自己继承了一些RMI代码,但运行它并没有太多麻烦。我们做的一件事就是将我们编译的jar与客户端和服务器都打包在一起。至少可以确保所有相同的内部类定义可用。 – gnomed

+0

另外,在开发环境之外运行代码时,您确定要使用JDK 1.5或更高版本吗?我相信自动生成代理的功能在JDK 1.5中提供,并且仅用于扩展UnicastRemoteObject的服务器,否则您将强制rmic您的服务器并自行生成存根。 –

回答

0

经过一番深入调查并按照RMI教程就显得有在端口1099

的RMI注册服务器的一个问题。当我盯着另一个端口(例如2005)的RMI注册服务器,改变了这些线路代码

LocateRegistry.createRegistry(2005); 

Naming.rebind("//127.0.0.1:2055/RmiServer", obj); 

这成功地运行,没有错误,我的客户是能够连接。

我希望这个答案可以帮助其他人解决这个错误。让我知道是否有人需要更详细的信息。

+2

只是改变端口号不会解决这个问题。我怀疑在1099上创建它时默默地失败了,因为已经有另一个注册表在其类路径中运行时没有存根,并且因为异常被抑制或忽略。 – EJP

0

您还没有再生存根与RMIC,或注册表不通过它的类路径访问它。

+0

嗨EJP,你能提供一些额外的解释吗?当RMI服务器程序移动到另一台机器时,是否需要重新生成存根文件 - 我可不只是将存根文件复制到另一台机器上?我刚刚尝试使用代码rmic org.prog.rmi.RmiServer重新生成它,这似乎没有什么区别。我不确定你的意思是“注册表无法通过它的类路径访问它” - 我需要在这里做什么? – Loftx

+0

@Loftx这是一个编译步骤,它不依赖于哪台机器。你可以复制它。您需要通过LocateRegistry在服务器JVM(推荐)中启动注册表,或者使用-J-Dclasspath启动* rmiregistry * =需要任何JAR文件。 – EJP