< 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 >