From 14f8e141097ea34fbead5afb421660583f94e701 Mon Sep 17 00:00:00 2001 From: jbachorik Date: Fri, 29 Jan 2016 13:35:06 +0100 Subject: [PATCH] 8146015: JMXInterfaceBindingTest is failing intermittently for IPv6 addresses Reviewed-by: dfuchs, sspitsyn --- .../bootstrap/JMXAgentInterfaceBinding.java | 25 ++++++--- .../bootstrap/JMXInterfaceBindingTest.java | 56 ++++++++++++------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java b/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java index 8b46a4c31..4647f280f 100644 --- a/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java +++ b/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java @@ -130,7 +130,7 @@ public class JMXAgentInterfaceBinding { private static class JMXConnectorThread extends Thread { - private final InetAddress addr; + private final String addr; private final int jmxPort; private final int rmiPort; private final boolean useSSL; @@ -139,7 +139,7 @@ public class JMXAgentInterfaceBinding { private boolean jmxConnectWorked; private boolean rmiConnectWorked; - private JMXConnectorThread(InetAddress addr, + private JMXConnectorThread(String addr, int jmxPort, int rmiPort, boolean useSSL, @@ -163,11 +163,11 @@ public class JMXAgentInterfaceBinding { private void connect() throws IOException { System.out.println( "JMXConnectorThread: Attempting JMX connection on: " - + addr.getHostAddress() + " on port " + jmxPort); + + addr + " on port " + jmxPort); JMXServiceURL url; try { url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" - + addr.getHostAddress() + ":" + jmxPort + "/jmxrmi"); + + addr + ":" + jmxPort + "/jmxrmi"); } catch (MalformedURLException e) { throw new RuntimeException("Test failed.", e); } @@ -200,7 +200,7 @@ public class JMXAgentInterfaceBinding { } System.out.println( "JMXConnectorThread: connection to rmi socket worked host/port = " - + addr.getHostAddress() + "/" + rmiPort); + + addr + "/" + rmiPort); rmiConnectWorked = true; // Closing the channel without sending any data will cause an // java.io.EOFException on the server endpoint. We don't care about this @@ -224,7 +224,7 @@ public class JMXAgentInterfaceBinding { private static class MainThread extends Thread { private static final int WAIT_FOR_JMX_AGENT_TIMEOUT_MS = 500; - private final InetAddress bindAddress; + private final String addr; private final int jmxPort; private final int rmiPort; private final boolean useSSL; @@ -233,7 +233,7 @@ public class JMXAgentInterfaceBinding { private Exception excptn; private MainThread(InetAddress bindAddress, int jmxPort, int rmiPort, boolean useSSL) { - this.bindAddress = bindAddress; + this.addr = wrapAddress(bindAddress.getHostAddress()); this.jmxPort = jmxPort; this.rmiPort = rmiPort; this.useSSL = useSSL; @@ -259,7 +259,7 @@ public class JMXAgentInterfaceBinding { private void waitUntilReadyForConnections() { CountDownLatch latch = new CountDownLatch(1); JMXConnectorThread connectionTester = new JMXConnectorThread( - bindAddress, jmxPort, rmiPort, useSSL, latch); + addr, jmxPort, rmiPort, useSSL, latch); connectionTester.start(); boolean expired = false; try { @@ -294,4 +294,13 @@ public class JMXAgentInterfaceBinding { } } + /** + * Will wrap IPv6 address in '[]' + */ + static String wrapAddress(String address) { + if (address.contains(":")) { + return "[" + address + "]"; + } + return address; + } } diff --git a/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java b/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java index 881f917a2..4a48278af 100644 --- a/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java +++ b/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java @@ -23,8 +23,10 @@ import java.io.File; import java.net.InetAddress; -import java.net.UnknownHostException; +import java.net.NetworkInterface; +import java.net.SocketException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -74,23 +76,24 @@ public class JMXInterfaceBindingTest { "truststore"; public static final String TEST_CLASSPATH = System.getProperty("test.classes", "."); - public void run(InetAddress[] addrs) { + public void run(List addrs) { System.out.println("DEBUG: Running tests with plain sockets."); runTests(addrs, false); System.out.println("DEBUG: Running tests with SSL sockets."); runTests(addrs, true); } - private void runTests(InetAddress[] addrs, boolean useSSL) { - TestProcessThread[] jvms = new TestProcessThread[addrs.length]; - for (int i = 0; i < addrs.length; i++) { + private void runTests(List addrs, boolean useSSL) { + TestProcessThread[] jvms = new TestProcessThread[addrs.size()]; + for (int i = 0; i < addrs.size(); i++) { + String addr = JMXAgentInterfaceBinding.wrapAddress(addrs.get(i).getHostAddress()); System.out.println(); String msg = String.format("DEBUG: Launching java tester for triplet (HOSTNAME,JMX_PORT,RMI_PORT) == (%s,%d,%d)", - addrs[i].getHostAddress(), + addr, JMX_PORT, RMI_PORT); System.out.println(msg); - jvms[i] = runJMXBindingTest(addrs[i], useSSL); + jvms[i] = runJMXBindingTest(addr, useSSL); jvms[i].start(); System.out.println("DEBUG: Started " + (i + 1) + " Process(es)."); } @@ -119,15 +122,15 @@ public class JMXInterfaceBindingTest { } } if (failedProcesses > 0) { - throw new RuntimeException("Test FAILED. " + failedProcesses + " out of " + addrs.length + " process(es) failed to start the JMX agent."); + throw new RuntimeException("Test FAILED. " + failedProcesses + " out of " + addrs.size() + " process(es) failed to start the JMX agent."); } } - private TestProcessThread runJMXBindingTest(InetAddress a, boolean useSSL) { + private TestProcessThread runJMXBindingTest(String address, boolean useSSL) { List args = new ArrayList<>(); args.add("-classpath"); args.add(TEST_CLASSPATH); - args.add("-Dcom.sun.management.jmxremote.host=" + a.getHostAddress()); + args.add("-Dcom.sun.management.jmxremote.host=" + address); args.add("-Dcom.sun.management.jmxremote.port=" + JMX_PORT); args.add("-Dcom.sun.management.jmxremote.rmi.port=" + RMI_PORT); args.add("-Dcom.sun.management.jmxremote.authenticate=false"); @@ -140,14 +143,14 @@ public class JMXInterfaceBindingTest { args.add("-Djavax.net.ssl.trustStorePassword=trustword"); } args.add(TEST_CLASS); - args.add(a.getHostAddress()); + args.add(address); args.add(Integer.toString(JMX_PORT)); args.add(Integer.toString(RMI_PORT)); args.add(Boolean.toString(useSSL)); try { ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(args.toArray(new String[] {})); System.out.println(ProcessTools.getCommandLine(builder)); - TestProcessThread jvm = new TestProcessThread("JMX-Tester-" + a.getHostAddress(), JMXInterfaceBindingTest::isJMXAgentResponseAvailable, builder); + TestProcessThread jvm = new TestProcessThread("JMX-Tester-" + address, JMXInterfaceBindingTest::isJMXAgentResponseAvailable, builder); return jvm; } catch (Exception e) { throw new RuntimeException("Test failed", e); @@ -173,8 +176,8 @@ public class JMXInterfaceBindingTest { } public static void main(String[] args) { - InetAddress[] addrs = getAddressesForLocalHost(); - if (addrs.length < 2) { + List addrs = getAddressesForLocalHost(); + if (addrs.size() < 2) { System.out.println("Ignoring manual test since no more than one IPs are configured for 'localhost'"); return; } @@ -183,14 +186,29 @@ public class JMXInterfaceBindingTest { System.out.println("All tests PASSED."); } - private static InetAddress[] getAddressesForLocalHost() { - InetAddress[] addrs; + private static List getAddressesForLocalHost() { try { - addrs = InetAddress.getAllByName("localhost"); - } catch (UnknownHostException e) { + List filtered = new ArrayList<>(); + for (NetworkInterface iface: Collections.list(NetworkInterface.getNetworkInterfaces())) { + for (InetAddress addr: Collections.list(iface.getInetAddresses())) { + if (isNonloopbackLocalhost(addr)) { + filtered.add(addr); + } + } + } + return filtered; + } catch (SocketException e) { throw new RuntimeException("Test failed", e); } - return addrs; + } + + // we need 'real' localhost addresses only (eg. not loopback ones) + // so we can bind the remote JMX connector to them + private static boolean isNonloopbackLocalhost(InetAddress i) { + if (!i.isLoopbackAddress()) { + return i.getHostName().toLowerCase().equals("localhost"); + } + return false; } private static class TestProcessThread extends Thread { -- GitLab