Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
807 views
in Technique[技术] by (71.8m points)

java - RMI lookup works but method invocation not

UPDATE:

The problem is, that i'm using a kind of 2-way connection.

On client side, this works:

String a = this.lobby.getMsg();

and this not:

this.lobby.login((Player)UnicastRemoteObject.exportObject(player, 0));

and ideas?



I'm working on a java application which uses RMI for network communication.

On one computer everythings works good, but if i try to run it via the internet i ran into problems.

It seems, that the client is able to retreive the registry from the server and to lookup the lobby-object. But if the client tries to call the login method of the lobby object via rmi, it takes very long time and i receive the following exception:

Strange thing is, that there is the wrong ip(the client ip) mentioned in this exception. And if I run a client on the same machine as the server, it works perfectly.

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.ConnectException: Connection refused to host: <client ip(should be server ip?)>; nested exception is: 
    java.net.ConnectException: Die Wartezeit für die Verbindung ist abgelaufen (=time out)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:353)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:160)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
    at $Proxy0.einloggen(Unknown Source)
    at Client.login(Client.java:64)

Here is the relevant code:

My server class:

    public static final int RMI_PORT = 55555;
    public static final String SERVER_IP = "xyz.com";

    /**
     * Startet Spielserver
     * 
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("Server starten..");

        System.setProperty("java.rmi.server.hostname", SERVER_IP);
        try {
            if (System.getSecurityManager() == null) {
                System.setSecurityManager(new RMISecurityManager());
            }

            Registry registry = LocateRegistry.getRegistry(SERVER_IP, RMI_PORT);

            Lobby lobby = new LobbyImpl();
            UnicastRemoteObject.exportObject(lobby, 0);
            registry.bind("Lobby", lobby);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (AlreadyBoundException e) {
            e.printStackTrace();
        }
    }

Client class:

public Client() {
        try {
            Registry registry = LocateRegistry.getRegistry("xyz.com", Server.RMI_PORT);
            lobby = (Lobby) registry.lookup("Lobby");
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (NotBoundException e) {
            e.printStackTrace();
        }
        this.gui = new GUI(this);
    }

    public void login(String name) throws RemoteException {
        Player player = new Player(name);
        this.lobby.login((Player)UnicastRemoteObject.exportObject(player, 0));  
    }

Client startscript:

#!/bin/bash
SCRIPTDIR=$(dirname $0)
java -classpath $SCRIPTDIR/bin Client

Server startscript:

#!/bin/bash
SCRIPTDIR=$(dirname $0)

cd ${SCRIPTDIR}/bin
rmiregistry 55555 &
cd - 
java -classpath $SCRIPTDIR/bin -Djava.security.policy=$SCRIPTDIR/src/server.policy -Djava.rmi.server.codebase=file:$SCRIPTDIR/bin/ Server
killall rmiregistry

and last but not least my first (test) policy file:

grant {
    permission java.security.AllPermission;
};

what could be the problem?

regards

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You need to look at item A.1 of the RMI FAQ on the RMI home page. The problem here is that the wrong IP address is being embedded into the remote stub. So the lookup works, because you are specifying the target IP address yourself in the client, but when you execute the remote method you are relying on the IP address in the stub, which is wrong. The solution is either to correct your /etc/hosts file or to set the system property java.rmi.server.hostname at the server JVM.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...