【问题标题】:Java RMI ImplementationJava RMI 实现
【发布时间】:2017-01-19 16:06:21
【问题描述】:

我有一个典型的客户端和服务器情况,我希望客户端能够从服务器上运行的对象调用方法。我使用 Java RMI 来解决这种情况。

服务器端代码如下,编译运行良好:

ServerInt.java

package gpio.control;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface ServerInt extends Remote{
    public void setHeizung(boolean x) throws RemoteException;
    public void quitError() throws RemoteException;
    public void startPWM(int periode,int pulsbreite,int pulsanzahl) throws RemoteException;
}

ServerImpl.java

package gpio.control;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteServer;
import java.rmi.server.UnicastRemoteObject;

public class ServerImpl implements ServerInt{
    private Model myModel;

    public ServerImpl(Model m) throws RemoteException {
        myModel = m;

        LocateRegistry.createRegistry(1099);
        ServerInt stub = (ServerInt) UnicastRemoteObject.exportObject(this, 1099);
        RemoteServer.setLog(System.out);

        Registry registry = LocateRegistry.getRegistry();
        registry.rebind("Server1", stub);
    }

    @Override
    public void setHeizung(boolean x) throws RemoteException {
        myModel.setHeizung(x);
    }

    @Override
    public void quitError() throws RemoteException {
        myModel.quitError();
    }

    @Override
    public void startPWM(int periode, int pulsbreite, int pulsanzahl) throws RemoteException {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

出于测试目的,我还创建了一个小型客户端应用程序,它与服务器应用程序在同一台服务器上运行:

客户端.java

package client;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

    public static void main(String[] args) throws RemoteException, NotBoundException {
        Registry registry = LocateRegistry.getRegistry();
        ServerInt serverint = (ServerInt) registry.lookup("rmi://127.0.0.1:1099/Server1"); 
        serverint.setHeizung(true);
    }

}

当我现在运行客户端程序时,我收到以下错误: 来自客户端的错误:

Exception in thread "main" java.rmi.NotBoundException: rmi://localhost:1099/Server1
    at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:166)
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:410)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$241(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:379)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at client.Client.main(Client.java:12)

来自服务器的错误:

Sep 07, 2016 9:47:04 AM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-127.0.0.1: [127.0.0.1: sun.rmi.registry.RegistryImpl[0:0:0, 0]: void rebind(java.lang.String, java.rmi.Remote)]
Sep 07, 2016 9:47:04 AM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(2)-127.0.0.1: [127.0.0.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Sep 07, 2016 9:47:05 AM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(3)-127.0.0.1: [127.0.0.1: sun.rmi.registry.RegistryImpl[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
Sep 07, 2016 9:47:05 AM sun.rmi.server.UnicastServerRef logCallException
FINE: RMI TCP Connection(3)-127.0.0.1: [127.0.0.1] exception:
java.rmi.NotBoundException: rmi://localhost:1099/Server1
    at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:166)
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:410)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$241(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我在这里做错了什么?

【问题讨论】:

  • @Mr_Thorynque 不,他没有,这里没有其他建议。

标签: java server raspberry-pi client-server rmi


【解决方案1】:

在 Client.java 中更改

registry.lookup("rmi://127.0.0.1:1099/Server1")

registry.lookup("Server1");

【讨论】:

    【解决方案2】:

    当您使用Registry 而不是Naming 进行查找时,您应该省略查找字符串的URL 部分,就像您在绑定时所做的那样。您应该只查找 Server1,就像绑定时一样。

    【讨论】:

    • 我将其更改为“Server1”,但这样做后我收到了 UnmarshalException: "java.lang.ClassNotFoundException gpio.control.ServerInt (no security manager: RMI class loader disabled) 所以我添加了 System. setSecurityManager(new SecurityManager()); 到客户端和服务器,但现在我得到一个 AccessControlException
    • 所以你有一个解决这个问题的方法,你现在有一个不同的问题。添加SecurityManager 不是解决方案,至少不是其本身。部署命名的类就是解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多