title: Java rmi over the internet
body: <p>I am developing a game in Java using RMI for all network communication. RMI allows me to call method on my server, but it is not enough for me. I also want the server to be able to spread message among connected clients.</p>
  
  <p>My clients look up for the server (it's interface extends Remote) and register on it. It allows the server to know who is connected. My clients also implement an interface that extends Remote. Here is some part of my code:</p>
  
  <p>Interfaces declaration:</p>
  
  <pre><code>public interface IServer extends Remote {
      void connect(IClient Client) throws RemoteException, ExistingItemException;
      //...
  }
  
  public interface IClient extends Remote {
      public void notify(Notification Notification) throws RemoteException;
      //...
  }
  </code></pre>
  
  <p>Server side:</p>
  
  <pre><code>//int RMIPort = 1099, ServerPort = 1100;
  IServer Server = new RMIServer();
  IServer Proxy = (IServer) UnicastRemoteObject.exportObject(Server, ServerPort);
  LocateRegistry.createRegistry(RMIPort).rebind("//" + LocalIP + ":" + 
          RMIPort + "/xxx", Proxy);
  </code></pre>
  
  <p>Client side:</p>
  
  <pre><code>//Sets the local reference to IServer and creates the IClient
  setInstance(new Client(Login, (IServer) LocateRegistry.getRegistry(RemoteIP).
          lookup("//" + RemoteIP + ":" + RMIPort + "/xxx")));
  //Gets the IClient and makes it available for the IServer to call notify(...)
  Proxy.connect((IClient) (UnicastRemoteObject.exportObject(getInstance(), 0)));
  </code></pre>
  
  <p>This solution works in local but doesn't when I'm trying to use it through Internet.</p>
  
  <p>I have setup my router to expose my computer to a fix IP address and forward the 1099 and 1100 ports. This solution allow other developers to "lookup" my server and get a valid and usable Proxy, but it doesn't allow them to export their IClient. It seems that the JVM tries to export the object to their local network and the execution stops here.</p>
  
  <p>So, I have tried to pass <code>-Djava.rmi.server.hostname=my-external-IP</code> JVM argument both local for my server and remote for clients. Doing so, exportObject throws a <code>ConnectException</code> to the remote ip instead of local one.</p>