UniqueIdSeed.java
package org.microspace.util;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
/**
* UniqueId is using this seed internally.
*
* @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
* @version 2016-06-26
*/
class UniqueIdSeed {
private static final byte[] DEFAULT_MAC = { 0, 0, 0, 0, 0 , 0 };
public enum ProcessIdSource {
NONE, JMX, PROCHANDLE, PROCFS
}
private byte[] macAddress;
private long time;
private int processId;
ProcessIdSource processIdSource;
public UniqueIdSeed() {
processIdSource = ProcessIdSource.NONE;
byte [] mac = null;
try {
Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
while (nifs.hasMoreElements()) {
NetworkInterface nif = nifs.nextElement();
if (nif.isLoopback()) continue;
if (nif.isVirtual()) continue;
if (!nif.isUp()) continue;
mac = nif.getHardwareAddress();
if (mac != null) break;
}
if (mac == null) mac = DEFAULT_MAC;
} catch (SocketException e) {
mac = DEFAULT_MAC;
}
macAddress = mac;
// From http://stackoverflow.com/questions/35842/how-can-a-java-program-get-its-own-process-id
// Works everywhere till RunTimeMXBean exists
if (processIdSource == ProcessIdSource.NONE) {
try {
// Using reflexion for this java9 feature.
//processId = (int)ProcessHandle.current().pid();
Class<?> processHandleClass =
Class.forName("java.lang.ProcessHandle");
Method currentMethod = processHandleClass.getMethod("current");
Object processHandleInstance = currentMethod.invoke(null);
Method pidMethod =processHandleClass.getMethod("pid");
//pidMethod.setAccessible(true);
processId = (int) ((long) pidMethod.invoke(processHandleInstance));
processIdSource = ProcessIdSource.PROCHANDLE;
} catch (Exception ex) {
// ex.printStackTrace();
}
}
if (processIdSource == ProcessIdSource.NONE) {
try {
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
Object mgmt = jvm.get(runtime);
java.lang.reflect.Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
processId = (Integer) pid_method.invoke(mgmt);
processIdSource = ProcessIdSource.JMX;
} catch (Exception e0) {
}
}
if (processIdSource == ProcessIdSource.NONE) {
// Linux only.
try {
processId = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
processIdSource = ProcessIdSource.PROCFS;
} catch (Exception e) {
}
}
time = System.currentTimeMillis();
}
public byte[] getMacAddress() {
return macAddress;
}
public long getTime() {
return time;
}
public int getProcessId() {
return processId;
}
public ProcessIdSource getProcessIdSource() {
return processIdSource;
}
}