Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8031753

JMXServiceURL should not use getLocalHost or its usage should be enhanced

    XMLWordPrintable

Details

    Description

      FULL PRODUCT VERSION :
      java version "1.7.0_45"
      OpenJDK Runtime Environment (rhel-2.4.3.4.0.1.el6_5-x86_64 u45-b15)
      OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Oracle Enterprise Linux 6:
      Linux server1 3.8.13-16.2.1.el6uek.x86_64 #1 SMP Thu Nov 7 17:01:44 PST 2013 x86_64 x86_64 x86_64 GNU/Linux


      EXTRA RELEVANT SYSTEM CONFIGURATION :
      [root@server1 Program4STR]# ifconfig
      eth0 Link encap:Ethernet HWaddr 08:00:27:8F:AA:41
                inet addr:192.168.11.66 Bcast:192.168.11.255 Mask:255.255.255.0
                inet6 addr: fe80::a00:27ff:fe8f:aa41/64 Scope:Link
                UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
                RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1000
                RX bytes:0 (0.0 b) TX bytes:888 (888.0 b)

      eth1 Link encap:Ethernet HWaddr 08:00:27:DF:29:64
                inet addr:192.168.55.66 Bcast:192.168.55.255 Mask:255.255.255.0
                inet6 addr: fe80::a00:27ff:fedf:2964/64 Scope:Link
                UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
                RX packets:2810 errors:0 dropped:0 overruns:0 frame:0
                TX packets:1996 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1000
                RX bytes:244690 (238.9 KiB) TX bytes:448383 (437.8 KiB)

      lo Link encap:Local Loopback
                inet addr:127.0.0.1 Mask:255.0.0.0
                inet6 addr: ::1/128 Scope:Host
                UP LOOPBACK RUNNING MTU:65536 Metric:1
                RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:0
                RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)


      A DESCRIPTION OF THE PROBLEM :
      During successful Agent running a getHost() method of JMXServiceURL is used only in two places and in general it's value is ignored because Agent is always started at all interfaces (i.e. 0.0.0.0 for IPv4)

      1) encodeStubInAddress method of javax.management.remote.rmi.RMIConnectorServer

          private void encodeStubInAddress(
                  RMIServer rmiServer, Map<String, ?> attributes)
                  throws IOException {

              final String protocol, host;
              final int port;

              if (address == null) {
                  if (IIOPHelper.isStub(rmiServer))
                      protocol = "iiop";
                  else
                      protocol = "rmi";
                  host = null; // will default to local host name
                  port = 0;
              } else {
                  protocol = address.getProtocol();
                  host = (address.getHost().equals("")) ? null : address.getHost(); // <---------------- getHost() IS USED HERE
                  port = address.getPort();
              }

              final String urlPath = encodeStub(rmiServer, attributes);

              address = new JMXServiceURL(protocol, host, port, urlPath);
          }


      2) exportMBeanServer method of sun.management.jmxremote.ConnectorBootstrap

          private static JMXConnectorServerData exportMBeanServer(
                  MBeanServer mbs,
                  int port,
                  int rmiPort,
                  boolean useSsl,
                  boolean useRegistrySsl,
                  String sslConfigFileName,
                  String[] enabledCipherSuites,
                  String[] enabledProtocols,
                  boolean sslNeedClientAuth,
                  boolean useAuthentication,
                  String loginConfigName,
                  String passwordFileName,
                  String accessFileName)
                  throws IOException, MalformedURLException {

              /* Make sure we use non-guessable RMI object IDs. Otherwise
               * attackers could hijack open connections by guessing their
               * IDs. */
              System.setProperty("java.rmi.server.randomIDs", "true");

              JMXServiceURL url = new JMXServiceURL("rmi", null, rmiPort);

      ...(skipped)

              JMXConnectorServer connServer = null;
              try {
                  connServer =
                          JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
                  connServer.start();
              } catch (IOException e) {

      ...(skipped)

              int registryPort =
                  ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort();
              String jmxUrlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi",
                                                 url.getHost(), registryPort); // <---------------- getHost() IS USED HERE
              JMXServiceURL remoteURL = new JMXServiceURL(jmxUrlStr);



      REGRESSION. Last worked in version 7u45

      ADDITIONAL REGRESSION INFORMATION:
      The issue has been also reproduced on the latest branches of jdk8 and jdk9.

      The issue derives from another project (Cassandra) and does not depend on it (i.e. the same issue is also present in another projects - just google the error message).


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      STR:
      1) install Oracle 6 or RedHat 6 linux and java package
      2) set hostname to 'server1'
      3) write a simple program (see in detailed description) and run it via JMX agent by the following script:

      [root@server1 Program4STR]# cat e
      #!/bin/sh

      JVM_OPTS="$JVM_OPTS -Djava.net.preferIPv4Stack=true"
      JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.port=7199"
      JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl=false"
      JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
      java $JVM_OPTS Program4STR

      4) the following issue appears:

      4.1) If server1 is not present in /etc/hosts and is not resolved via DNS then program throws the following error:

      Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: server1: server1

      !!!!! BUT !!!!!

      4.2) If server1 has a record in /etc/hosts with a not valid IP then agent starts successfully.
      For example:
      4.2.1) if the following record is present in /etc/hosts:
      192.168.11.11 server1
      4.2.2) but this IP is not assigned to any interface
      [root@server1 Program4STR]# ifconfig | grep 192.168.11.11
      [root@server1 Program4STR]#
      4.2.3) And agent is started without any exception:
      [marbug@server1 Program4STR]$ netstat -na | grep 7199
      tcp 0 0 0.0.0.0:7199 0.0.0.0:* LISTEN

      4.3) if server1 is resolved via DNS to an IP of another PC then agent also starts successfully.
      For example:
      4.3.1) connect this PC to another WiFi network (by DHCP)
      4.3.2) server1 is resolved to an IP of another PC
      4.3.3) but agent starts successfully
      [marbug@server1 Program4STR]$ netstat -na | grep 7199
      tcp 0 0 0.0.0.0:7199 0.0.0.0:* LISTEN

      4.4) etc


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      1) Agent should not depend on hostname and must be started even if hostname can't be resolved because it is started even if hostname is resolved to incorrect or not assigned IP (i.e. Agent is always started on all interfaces, i.e. on 0.0.0.0).

      2) JMXServiceURL should use 'localhost' but not current PC hostname if host is null.

      P.S. Indeed Agent should support com.sun.management.jmxremote.host=192.168.55.66 option, Agent must be started on this specified (in com.sun.management.jmxremote.host) IP and JMXServiceURL must use this value but it's a subject of another ticket.
      ACTUAL -
      Agent throws an exception if hostname can't be resolved to IP


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      StackTrace:

      [Wed Jan 15 03:41:19 EET 2014]
          0 CLASS[java.lang.Thread] FILE[Thread.java] LINE[1568] METHOD[getStackTrace]
          1 CLASS[marbug.MarBugLogger] FILE[MarBugLogger.java] LINE[15] METHOD[log_message]
          2 CLASS[javax.management.remote.JMXServiceURL] FILE[JMXServiceURL.java] LINE[285] METHOD[<init>]
          3 CLASS[javax.management.remote.JMXServiceURL] FILE[JMXServiceURL.java] LINE[250] METHOD[<init>]
          4 CLASS[sun.management.jmxremote.ConnectorBootstrap] FILE[ConnectorBootstrap.java] LINE[732] METHOD[exportMBeanServer]
          5 CLASS[sun.management.jmxremote.ConnectorBootstrap] FILE[ConnectorBootstrap.java] LINE[457] METHOD[startRemoteConnectorServer]
          6 CLASS[sun.management.Agent] FILE[Agent.java] LINE[260] METHOD[startAgent]
          7 CLASS[sun.management.Agent] FILE[Agent.java] LINE[456] METHOD[startAgent]
              [JMXServiceURL method] exception: java.net.UnknownHostException: server1: server1


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      I am able to reproduce the issue by a simple program:

      [root@server1 Program4STR]# cat Program4STR.java
      import java.util.Scanner;

      public class Program4STR
      {
          public static void main(String[] args)
          {
              System.out.println("Please input something");
              Scanner scanner = new Scanner( System.in );
              try {
                  scanner.findInLine( "(\\S+)" );
              }
              catch ( Exception e ) {
              }
              System.out.println("Done");
          }
      }



      I run it by:

      [root@server1 Program4STR]# cat e
      vJavaVersion=$1

      JVM_OPTS="$JVM_OPTS -Djava.net.preferIPv4Stack=true"
      JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.port=7199"
      JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl=false"
      JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
      #JVM_OPTS="$JVM_OPTS -XX:+TraceClassLoading -XX:+TraceClassUnloading"

      java_path="java"
      if [ "$vJavaVersion" = "7" ]; then
          java_path="/home/marbug/cpp/jab/tmp/jdk7u40/build/linux-amd64/bin/java"
      fi
      if [ "$vJavaVersion" = "8" ]; then
          java_path="/home/marbug/cpp/jab/tmp/jdk8/build/linux-x86_64-normal-server-release/jdk/bin/java"
      fi
      if [ "$vJavaVersion" = "9" ]; then
          java_path="/home/marbug/cpp/jab/tmp/jdk9/build/linux-x86_64-normal-server-release/jdk/bin/java"
      fi
      ${java_path} $JVM_OPTS Program4STR

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
                   try {
      - local = InetAddress.getLocalHost();
      + local = InetAddress.getByName("localhost");
                   } catch (UnknownHostException e) {

      Attachments

        Activity

          People

            hb Harsha Wardhana B (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: