5

How can I get the unix hostid into Java through some sort of call?

http://linux.about.com/library/cmd/blcmdl1_hostid.htm

jww
  • 97,681
  • 90
  • 411
  • 885
mainstringargs
  • 13,563
  • 35
  • 109
  • 174
  • 1
    it seems that `hostid` is a program so the see http://stackoverflow.com/questions/5053766/run-ms-dos-command-from-java-program/5053790#5053790 – Dan D. Jun 23 '11 at 22:02
  • 1
    Yeah, but you can get the same info directly in Java; see my solution below. – David R Tribble Jun 23 '11 at 23:13
  • For IPv4 machines it is possible to read the hostid form /etc/hostid or calcuate it from the hostname's ip address. That way you don't have to call another program to get the result. See below. – Edwin Buck Jun 25 '11 at 00:44
  • Possible duplicate of [Getting a unique id from a unix-like system](https://stackoverflow.com/q/328936/608639). – jww May 28 '18 at 11:19

5 Answers5

2

If it has been set by a previous call to sethostid(long int id) it will reside in the HOSTIDFILE, typically /etc/hostid.

If it is not there, you fetch the machine's hostname. You pull out the address for the hostname, and if that's IPv4, it is the IPv4 address formatted from dotted decimal to binary with the top 16 bits and the lower 16 bits swapped.

InetAddress addr = InetAddress.getLocalHost();
byte[] ipaddr = addr.getAddress();
if (ipaddr.length == 4) {
  int hostid = 0 | ipaddr[1] << 24 | ipaddr[0] << 16 | ipaddr[3] << 8 | ipaddr[2];
  StringBuilder sb = new StringBuilder();
  Formatter formatter = new Formatter(sb, Locale.US);
  formatter.format("%08x", hostid);
  System.out.println(sb.toString());
} else {
  throw new Exception("hostid for IPv6 addresses not implemented yet");
}
Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
1

You're going to have to write JNI (or JNA), I'm afraid.

Edward Thomson
  • 74,857
  • 14
  • 158
  • 187
  • 1
    Or use `Runtime`, or even pass it as a parameter – Johan Sjöberg Jun 23 '11 at 22:05
  • 1
    True. If this is for an internal system that I controlled, I would be okay with exec()ing. But if this was an app I was shipping, then I would use JNI as godonlyknows what clients have done to their poor machines. – Edward Thomson Jun 24 '11 at 01:48
1

Perhaps the following article will help.

http://www.devdaily.com/java/java-exec-processbuilder-process-1

dave
  • 1,520
  • 11
  • 8
1

Call Runtime.exec(String) where the argument is the path to the "hostid" executable then, drain both streams of the resulting Process object and take the contents of the standard output stream as your string value.

This simple class demonstrates how you could implement this strategy (but needs improvement for error handling [e.g. stderr, exceptions] and OOP best-practices [e.g. returning an object with bean properties, etc.]):

public class RunCommand {
  public static String exec(String command) throws Exception {
    Process p = Runtime.getRuntime().exec(command);
    String stdout = drain(p.getInputStream());
    String stderr = drain(p.getErrorStream());
    return stdout; // TODO: return stderr also...
  }
  private static String drain(InputStream in) throws IOException {
    int b = -1;
    StringBuilder buf = new StringBuilder();
    while ((b=in.read()) != -1) buf.append((char) b);
    return buf.toString();
  }
}

Your program could use it as such:

String myHostId = RunCommand.exec("/usr/bin/hostid").trim();

Note that using a ProcessBuilder to create the Process might be more appropriate than Runtime.exec() if your command needs arguments or an environment, etc.

maerics
  • 151,642
  • 46
  • 269
  • 291
-2

Try this (wrapped in some class, of course):

import java.net.InetAddress;
import java.net.UnknownHostException;

public static String getLocalHostIP()
    throws UnknownHostException
{
    InetAddress  ip;

    ip = InetAddress.getLocalHost();
    return ip.getHostAddress();
}

The method returns a string of the form "xxx.xxx.xxx.xxx".

UPDATE

An improved method is:

// Determine the IP address of the local host
public static String getLocalHostIP()
{
    try
    {
        return InetAddress.getLocalHost().getHostAddress();
    }
    catch (UnknownHostException ex)
    {
        return null;
    }
}
David R Tribble
  • 11,918
  • 5
  • 42
  • 52
  • 3
    The hostid is not the IP address. – Edward Thomson Jun 24 '11 at 01:44
  • @Edward: Okay, then, disregard. – David R Tribble Jun 24 '11 at 19:44
  • @Edward, Actually I've read the glibc implementation of hostid on Linux, it is the IP address, cast into a 32 bit unsigned integer, with the lower 16 bits and the higher 16 bits swapped. That's why I wrote the code snipped above, which returns exactly the same value for hostid as the hostid program (on my system). – Edwin Buck Jun 25 '11 at 15:03
  • @Edwin - I agree, but the info page does not make a guarantee of the implementation not changing in the future. Further, this value can be modified with sethostid(3). If this is strictly for machines that you control, then I agree that the implementor would know whether this is an appropriate solution. If you really need the value of the hostid, though, I posit that you actually need to call gethostid(3) (or exec a program that does the same thing.) – Edward Thomson Jun 27 '11 at 14:20
  • @Edward, changing the implementation is possible, but it means an update of glibc in a function that is provided for POSIX compliance. Yes, it could happen, but if the best they've come up with in 30 years is an IP address with some byte swapping, I'm not holding my breath. – Edwin Buck Jun 27 '11 at 14:42
  • @Edwin - well, gethostid and sethostid aren't defined by POSIX and the man and info pages don't guarantee how the value is determined. But my point is that the Java implementation depends on the audience: if you're distributing this application to end users, they will probably expect this to respect a hostid they've set. (Perhaps they want a consistent hostid when their IP addresses are dynamic. Perhaps an IP-based hostid is simply not unique in their environment because they have many offices behind NATs that share similar characteristics and they need uniqueness across those offices.) – Edward Thomson Jun 27 '11 at 14:51
  • @Edward, POSIX.1-2001 specifies gethostid(). To get a consistent hostid with a dynamic IP address, you'd have to poll it either way. None of the C / Shell / Java versions are built around listening models. Those who opt to use gethostid tend to know about its limitations, and they don't use it in environments which would make it unusable (for obvious reasons). – Edwin Buck Jun 27 '11 at 15:11
  • I stand corrected about the POSIX reference. In any case, I'm not sure what we're arguing about: you're stating that hostid is, by default, generated by swapping some bits on the IP address. I agree - this is simply a fact. I'm stating that users can set the hostid after the fact so that the mangled IP address does not accurately reflect a call to gethostid(3). This is also a fact. Whether this is a problem for the original poster's application is a judgement call that, without more knowledge, I don't think either of us can make. – Edward Thomson Jun 27 '11 at 15:55