1

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

URL 示例:rmi://(host):(port)/rule

功能示例: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) 在 java.security.AccessControlContext.checkPermission(AccessControlContext.java:374) 在 java.security.AccessController.checkPermission(AccessController.java:546) 在 java.lang .SecurityManager.checkPermission(SecurityManager.java:532) 在 java.lang.Thread.setContextClassLoader(Thread.java:1394) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 在 org.apache。 catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java: 174) 在 org.apache.coyote.http11.Http11Processor。org.apache.coyote.http11.Http11BaseProtocol 的进程(Http11Processor.java:874)$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) 在 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.security.AccessControlContext.checkPermission(AccessControlContext.java 处拒绝访问 (java.lang.RuntimePermission setContext ClassLoader) :374) 在 java.security。AccessController.checkPermission(AccessController.java:546) 在 java.lang.SecurityManager.checkPermission(SecurityManager.java:532) 在 java.lang.Thread.setContextClassLoader(Thread.java:1394) 在 org.apache.catalina.core.ContainerBase $ContainerBackgroundProcessor.processChildren(ContainerBase.java:1574) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1559) at java.lang.Thread.run(Thread.java:662)core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1559) at java.lang.Thread.run(Thread.java:662)core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1559) at 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 客户端调用接口,对吗?为什么不能投?界面有问题?

4

1 回答 1

0

您要么必须:

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

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

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

于 2013-03-21T02:31:22.467 回答