使用RMI从客户端调用服务器上的方法

时间:2013-03-20 02:58:54

标签: client rmi

我已获得连接服务器及其功能的URL。

网址示例:rmi://(host):(port)/rul e

功能示例:reloadRule()

基本上,我需要从客户端调用这个reloadRule函数。我尝试使用java RMI并创建rmiClient类和接口。

这是我的代码:

接口

import java.rmi.Remote;
     import java.rmi.RemoteException;

     public interface RmiServerIntf extends Remote{
           public void reloadRule() throws RemoteException;
     }

客户端

import java.rmi.Naming;

     public class RmiClient {
            RmiServerIntf obj = null; 

            public void reloadRule() { 
                 try { 
                   obj = (RmiServerIntf)Naming.lookup("rmi://localhost:8009/rule");
                   obj.reloadRule(); 
                 } catch (Exception e) { 
                   System.err.println("RmiClient exception: " + e); 
                   e.printStackTrace(); 
                 } 
            }     
     }

调用rmiClient的Java类

// invoke RMI service

        // Create and install a security manager
        /*
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new NullRMISecurityManager());
        } */
        RmiClient cli = new RmiClient();
        cli.reloadRule();
        System.out.println("Reload Rule");

我仍然很困惑如何运行这个东西?我尝试运行调用rmiClient的类,并获得此异常:

  

java.security.AccessControlException:访问被拒绝   (java.lang.RuntimePermission setContextClassLoader)           at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)           at java.security.AccessController.checkPermission(AccessController.java:546)           在java.lang.SecurityManager.checkPermission(SecurityManager.java:532)           at java.lang.Thread.setContextClassLoader(Thread.java:1394)           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)           在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)           在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)           在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)           在org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)           at org.apache.coyote.http11.Http11BaseProtocol $ Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)           在org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)           在org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)           at org.apache.tomcat.util.threads.ThreadPool $ ControlRunnable.run(ThreadPool.java:689)           在java.lang.Thread.run(Thread.java:662)           线程“ContainerBackgroundProcessor [StandardEngine [Catalina]]”中的异常   java.security.AccessControlException:访问被拒绝   (java.lang.RuntimePermission setContext            类加载器)            at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)           at java.security.AccessController.checkPermission(AccessController.java:546)           在java.lang.SecurityManager.checkPermission(SecurityManager.java:532)           at java.lang.Thread.setContextClassLoader(Thread.java:1394)           在org.apache.catalina.core.ContainerBase $ ContainerBackgroundProcessor.processChildren(ContainerBase.java:1574)           在org.apache.catalina.core.ContainerBase $ ContainerBackgroundProcessor.run(ContainerBase.java:1559)           在java.lang.Thread.run(Thread.java:662)

可以请一些亮点并指出我正确的方向。感谢。


更新

我删除了安全管理器并获得了此异常:

    RmiClient exception: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
    java.lang.ClassNotFoundException: org.springframework.remoting.rmi.RmiInvocationHandler (no security manager: RMI class loader disabled)
    java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
    java.lang.ClassNotFoundException: org.springframework.remoting.rmi.RmiInvocationHandler (no security manager: RMI class loader disabled)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Naming.java:84)

我的代码中缺少什么?这个错误意味着什么?


更新2

我在库中包含spring-2.5.4.jar。我得到了这个例外:

      RmiClient exception: java.lang.ClassCastException: $Proxy10 cannot be cast to admin.fsms.RmiServerIntf
      java.lang.ClassCastException: $Proxy10 cannot be cast to admin.fsms.RmiServerIntf

问题的根源在于:

      obj = (RmiServerIntf)Naming.lookup("rmi://localhost:8009/rule");

我应该在rmi客户端调用接口吗?为什么不能施展?界面出了什么问题?

1 个答案:

答案 0 :(得分:0)

你要么:

  1. 在客户端安装Spring JAR文件(以修复ClassNotFoundException

  2. 使用代码库功能(同上),这也意味着要恢复安全管理器,尽管您当然不应该自己编写:使用RMISecurityManager并编写正确的.policy文件,或

  3. 使用直接RMI而不是Spring来导出远程对象(以消除根本原因)。我对Spring一无所知,只是让你的远程对象自己将UnicastRemoteObjectrebind()扩展到注册表。