简体   繁体   中英

which hostname or ip is java rmi bind in linux?

i am new with java rmi. And i have a question about rmi usage.
Firstly, i created a server with port(the interface only has a port argument).

this.registry = LocateRegistry.createRegistry(1099);

Then i bind a server like this:


public interface MyRmiService extends Remote {
    // return "service name" for example
    String getName() throws RemoteException;
}

 public void register(MyRmiService service) {
        try {
            this.registry.rebind(syncDataService.getName(), service);
        } catch (RemoteException var3) {
            FineLoggerFactory.getLogger().error(var3.getMessage(), var3);
        }

}

and my client code is like this:

// linux ip
Registry tempRegistry = LocateRegistry.getRegistry(ip, 1099);
MyRmiService service = (MyRmiService)tempRegistry.lookup("service name");

These code looks fine if my machine ip looks the same with linux shell:

[root@node26 ~]# hostname
node26
[root@node26 ~]# hostname -i
192.168.101.26
[root@node26 ~]# hostname -I
192.168.101.26 192.168.122.1 172.17.0.1 

if i use 192.168.101.26 as ip.
But if i get some different ip like this:

# for example
[root@a ~]# hostname -I
172.16.5.199 172.17.0.1 
[root@iZbp124z80qrl3rd8pk42xZ ~]# hostname -i
10.162.107.99
[root@iZbp124z80qrl3rd8pk42xZ ~]# hostname
iZbp124z80qrl3rd8pk42xZ

It doesn't work fine and stuck in the client finding service with lookup .
Normally i want to use 172.16.5.199 as ip. But maybe rmi is using 10.162.107.99 which i cannot ping from client. Is this linux server has the right hostname config?
Then I'm confused.

  1. which hostname or ip is used when LocateRegistry.createRegistry(1099); called?
  2. which hostname or ip is used when registry.rebind(syncDataService.getName(), service); called?
  3. which ip should i use to call LocateRegistry.getRegistry(ip, 1099); ? My question is, what exactly the ip should i use?

TLDR: it's not the registry

To get your first and third questions out of the way

  • the registry created by LocateRegistry.createRegistry (like the one created by running the JRE/bin/registry[.exe] program ) listens on 0.0.0.0 for IPv4 and/or ::0 for IPv6 depending on your JVM config. This can receive on any address (and over any interface) that works in your OS.

  • LocateRegistry.getRegistry(String[,int]) connects to whatever address or name (resolved to an address) you specify; ([int]) calls InetAddress.getLocalHost() which dispatches to getLocalHostName() in Inet4AddressImp or Inet6AddressImpl depending on your JVM as above, but in either case that is a native method with implementation depending on your OS which for Unix including Linux is here or here . As you can see these are identical and thus it always calls gethostname() which should return the same value the hostname progam (with no options) displays; if the call fails (returns nonzero) Java substitutes the literal string "localhost" . That name is then resolved, typically by a host file and/or DNS but may vary depending on the OS and configuration; on a properly configured system gethostname() will be a name that resolves to a valid address of the machine (displayed by hostname -i ), while localhost is special-cased to always give the loopback address (for the IP version) which is a valid address only when used on the same machine ie not really RMI. (A properly configured OS also resolves localhost to loopback, but Java does so here even if the OS doesn't.) Note that none of these look at the addresses actually existing on your interfaces (which hostname -I returns).

That connection, to the registry, worked fine. You say it's the lookup call that hangs, and that is trying to connect to the remote service . This relates to your second question about registry.rebind(name, remoteobject) -- but it's not the rebind (or bind ) call that sets the location of the remoteobject, rather the remoteobject already contains its location. You use a parameter service without showing where it comes from and particularly where it was created, and that's what matters, because such an object is created to contain a LiveRef which in turn creates and contains a TCPEndpoint which contains the name or address to be used to connect it.

Now the code in TCPEndpoint which determines that name or address is a bit complicated. The simple case is that if sysprop java.rmi.server.hostname is set, that is used -- and can be either a resolvable name or an address in string form. Otherwise it calls InetAddress.getLocalHost() as described above for getRegistry and by default it uses the resulting address , but if sysprop java.rmi.server.useLocalHostName is set true it uses the name (ie from gethostname() ) except if the name doesn't contain a dot (doesn't 'look like' a DNS name) it attempts reverse resolution on the address and if successful uses that name; it's not quite clear to me what happens if that fails, and I can't easily test right now.

So the simple answer to your problem, but not your question, is use java.rmi.server.hostname to specify a name or address that the client(s) should use to reach your server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM