3

First off, I'd love to post some real code for this question, but I can't because it's far too many lines. That said, here's my situation:

Server Side

I have an RMI Server that waits for Clients to connect and "register" themselves, so that the Server can make function calls on Clients. Basically, the server has a published function that works like the following pseudo-code:

public class Server extends UnicastRemoteObject implements ServerInterface{
    public Server(){ /* Server publishes itself here */ }

    ...

    /** One of many methods visible to a remote Client */
    public void registerClient(Client c) throws RemoteException{
        //1. Make some remote calls on 'c' for book-keeping purposes
        //2. Store reference to c to make calls on it later
    }
}

Client Side

On Startup, the Client makes a call to Naming.lookup([url]) to get a stub to the Server that I'll call serverRef, then calls serverRef.registerClient(this). The problem happens the first line of the server's registerClient(Client c) method.

Problem

When the server makes its first remote method call to the Client inside the registerClient method, a RemoteException is thrown. While client and server machines are on the same subnet, the client's machine has a secondary IP address. So the IPs look something like this:

Server Machine IPs: 123.45.67.1
Client Machine IPs: 123.45.67.2, 192.168.67.2

The RemoteException that gets thrown during the Server's first remote call back to the client indicates that the Server is trying to connect to the Client's 192.168.67.2 address, which is what's causing the failure. The Server should be trying to connect to the 123.45.67.1 address. I know that disabling the network interface that belongs to the second IP address would fix the problem, but this isn't really an option for me.

Is there any way to "tell" server-side RMI which IP address to connect on when opening a connection to a new client-side object stub?

CodeBlind
  • 4,519
  • 1
  • 24
  • 36
  • 1
    If you are using a Strong Hosting Model OS, the source IP address can be specified. If you are using a weak hosting model OS (such as Linux), the OS ignores your hint as to the source IP and follows its routing tables. (Assuming you can get RMI to use a Socket this way) – Peter Lawrey Apr 27 '12 at 16:57

1 Answers1

1

There are several possible solutions, including

  • write a custom client socket factory

  • specify addresses in java.rmi.server.hostname property

    -Djava.rmi.server.hostname=ip_address

  • etc

Check out this link:

These links are also useful:

Community
  • 1
  • 1
paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • Thanks for the links! I think I'm going to go with writing a custom client socket factory - I'll let you know how it goes. – CodeBlind Apr 27 '12 at 17:17
  • 3
    Yep, that did the trick. I ended up implementing my own `RMISocketFactory` and used `RemoteServer.getClientHost()` inside the socket factory's `createSocket(String host, int port)` method, which ultimately gets called by my `registerClient(c)` method. I just replace the given host name with the one returned by the call to `getClientHost()` and it works perfectly every time. Thanks! – CodeBlind Apr 27 '12 at 19:11
  • Hi, Ben I have the exactly same problem. Can you publish the code you said above ? – emin Jan 18 '13 at 13:49