< prev index next >
src/java.management/share/classes/javax/management/remote/JMXServiceURL.java
Print this page
@@ -32,14 +32,19 @@
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.MalformedURLException;
+import java.net.NetworkInterface;
+import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.BitSet;
+import java.util.Enumeration;
import java.util.Locale;
import java.util.StringTokenizer;
/**
* <p>The address of a JMX API connector server. Instances of this class
@@ -234,14 +239,17 @@
* JMXServiceURL(protocol, host, port, null)}.</p>
*
* @param protocol the protocol part of the URL. If null, defaults
* to <code>jmxmp</code>.
*
- * @param host the host part of the URL. If null, defaults to the
- * local host name, as determined by
- * <code>InetAddress.getLocalHost().getHostName()</code>. If it
- * is a numeric IPv6 address, it can optionally be enclosed in
+ * @param host the host part of the URL. If host is null and if
+ * local host name can be resolved to an IP, then host defaults
+ * to local host name as determined by
+ * <code>InetAddress.getLocalHost().getHostName()</code>. If host is null
+ * and if local host name cannot be resolved to an IP, then host
+ * defaults to numeric IP address of one of the active network interfaces.
+ * If host is a numeric IPv6 address, it can optionally be enclosed in
* square brackets <code>[]</code>.
*
* @param port the port part of the URL.
*
* @exception MalformedURLException if one of the parts is
@@ -258,14 +266,17 @@
* <p>Constructs a <code>JMXServiceURL</code> with the given parts.
*
* @param protocol the protocol part of the URL. If null, defaults
* to <code>jmxmp</code>.
*
- * @param host the host part of the URL. If null, defaults to the
- * local host name, as determined by
- * <code>InetAddress.getLocalHost().getHostName()</code>. If it
- * is a numeric IPv6 address, it can optionally be enclosed in
+ * @param host the host part of the URL. If host is null and if
+ * local host name can be resolved to an IP, then host defaults
+ * to local host name as determined by
+ * <code>InetAddress.getLocalHost().getHostName()</code>. If host is null
+ * and if local host name cannot be resolved to an IP, then host
+ * defaults to numeric IP address of one of the active network interfaces.
+ * If host is a numeric IPv6 address, it can optionally be enclosed in
* square brackets <code>[]</code>.
*
* @param port the port part of the URL.
*
* @param urlPath the URL path part of the URL. If null, defaults to
@@ -284,36 +295,44 @@
if (host == null) {
InetAddress local;
try {
local = InetAddress.getLocalHost();
- } catch (UnknownHostException e) {
- throw new MalformedURLException("Local host name unknown: " +
- e);
- }
-
host = local.getHostName();
/* We might have a hostname that violates DNS naming
rules, for example that contains an `_'. While we
could be strict and throw an exception, this is rather
user-hostile. Instead we use its numerical IP address.
We can only reasonably do this for the host==null case.
If we're given an explicit host name that is illegal we
have to reject it. (Bug 5057532.) */
- try {
+ try{
validateHost(host, port);
- } catch (MalformedURLException e) {
+ }catch (MalformedURLException e){
if (logger.fineOn()) {
logger.fine("JMXServiceURL",
"Replacing illegal local host name " +
host + " with numeric IP address " +
"(see RFC 1034)", e);
}
host = local.getHostAddress();
- /* Use the numeric address, which could be either IPv4
- or IPv6. validateHost will accept either. */
+ }
+ } catch (UnknownHostException e) {
+ try {
+ /*
+ If hostname cannot be resolved, we will try and use numeric IPv4/IPv6 address.
+ If host==null, we know that agent will be started on all interfaces - 0.0.0.0
+ Hence we will use IP address of first active non-loopback interface
+ */
+ host = getActiveNetworkInterfaceIP();
+ if(host == null){
+ throw new MalformedURLException("Unable to resolve hostname or get valid IP address");
+ }
+ } catch (SocketException ex) {
+ throw new MalformedURLException("Unable to resolve hostname or get valid IP address");
+ }
}
}
if (host.startsWith("[")) {
if (!host.endsWith("]")) {
@@ -338,10 +357,36 @@
this.urlPath = urlPath;
validate();
}
+ private String getActiveNetworkInterfaceIP() throws SocketException{
+ Enumeration<NetworkInterface> networkInterface = NetworkInterface.getNetworkInterfaces();
+ String ipv6AddrStr = null;
+ while (networkInterface.hasMoreElements())
+ {
+ NetworkInterface nic = networkInterface.nextElement();
+ if(nic.isUp() && !nic.isLoopback()){
+ Enumeration<InetAddress> inet = nic.getInetAddresses();
+ while (inet.hasMoreElements())
+ {
+ InetAddress addr = inet.nextElement();
+ if (addr instanceof Inet4Address && !addr.isLinkLocalAddress()){
+ return addr.getHostAddress();
+ }else if (addr instanceof Inet6Address && !addr.isLinkLocalAddress()){
+ /*
+ We save last seen IPv6 address which we will return
+ if we do not find any interface with IPv4 address.
+ */
+ ipv6AddrStr = addr.getHostAddress();
+ }
+ }
+ }
+ }
+ return ipv6AddrStr;
+ }
+
private static final String INVALID_INSTANCE_MSG =
"Trying to deserialize an invalid instance of JMXServiceURL";
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gf = inputStream.readFields();
String h = (String)gf.get("host", null);
@@ -538,11 +583,13 @@
* parameter, the result is the substring specifying the host in
* that URL. If the Service URL was constructed with a
* constructor that takes a separate host parameter, the result is
* the string that was specified. If that string was null, the
* result is
- * <code>InetAddress.getLocalHost().getHostName()</code>.</p>
+ * <code>InetAddress.getLocalHost().getHostName()</code> if local host name
+ * can be resolved to an IP. Else numeric IP address of an active
+ * network interface will be used.</p>
*
* <p>In either case, if the host was specified using the
* <code>[...]</code> syntax for numeric IPv6 addresses, the
* square brackets are not included in the return value here.</p>
*
< prev index next >