From a70d3ad6194c4e5a9d609e90d876e917076d0063 Mon Sep 17 00:00:00 2001 From: Amit Sapre Date: Fri, 20 Jan 2017 04:42:29 -0800 Subject: [PATCH] 8167337: When jmxremote.port=0, JDP broadcasts "0" instead of assigned port Fetched the correct jmx service url for jdp to broadcast it. Reviewed-by: dsamersoff, rriggs --- .../share/classes/sun/management/Agent.java | 18 +-- .../sun/management/jdp/DynamicLauncher.java | 11 +- .../jdp/JdpJmxRemoteDynamicPortTest.java | 60 ++++++++++ .../jdp/JdpJmxRemoteDynamicPortTestCase.java | 106 ++++++++++++++++++ 4 files changed, 177 insertions(+), 18 deletions(-) create mode 100644 jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java create mode 100644 jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTestCase.java diff --git a/jdk/src/java.management/share/classes/sun/management/Agent.java b/jdk/src/java.management/share/classes/sun/management/Agent.java index fbc80433793..80c34e30452 100644 --- a/jdk/src/java.management/share/classes/sun/management/Agent.java +++ b/jdk/src/java.management/share/classes/sun/management/Agent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -502,19 +502,9 @@ public class Agent { } } - // Rebuilding service URL to broadcast it - String jmxremotePort = props.getProperty(JMXREMOTE_PORT); - String rmiPort = props.getProperty(RMI_PORT); - - JMXServiceURL url = jmxServer.getAddress(); - String hostname = url.getHost(); - - String jmxUrlStr = (rmiPort != null) - ? String.format( - "service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi", - hostname, rmiPort, hostname, jmxremotePort) - : String.format( - "service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", hostname, jmxremotePort); + // Get service URL to broadcast it + Map remoteProps = ConnectorAddressLink.importRemoteFrom(0); + String jmxUrlStr = remoteProps.get("sun.management.JMXConnectorServer.0.remoteAddress"); String instanceName = props.getProperty("com.sun.management.jdp.name"); diff --git a/jdk/test/sun/management/jdp/DynamicLauncher.java b/jdk/test/sun/management/jdp/DynamicLauncher.java index b8e5710dbef..934002c056b 100644 --- a/jdk/test/sun/management/jdp/DynamicLauncher.java +++ b/jdk/test/sun/management/jdp/DynamicLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,19 +38,19 @@ import java.util.UUID; public abstract class DynamicLauncher { final String jdpName = UUID.randomUUID().toString(); + OutputAnalyzer output; int jmxPort; protected void run() throws Exception { - OutputAnalyzer out; int retries = 1; boolean tryAgain; do { tryAgain = false; jmxPort = Utils.getFreePort(); - out = runVM(); + output = runVM(); try { - out.shouldNotContain("Port already in use"); + output.shouldNotContain("Port already in use"); } catch (RuntimeException e) { if (retries < 3) { retries++; @@ -71,4 +71,7 @@ public abstract class DynamicLauncher { protected abstract String[] options(); + protected OutputAnalyzer getProcessOutpoutAnalyzer() { + return output; + } } diff --git a/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java b/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java new file mode 100644 index 00000000000..9ee4a0cd820 --- /dev/null +++ b/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test JdpJmxRemoteDynamicPortTest.java + * @bug 8167337 + * @summary Verify a non-zero value is assigned to jmxremote.port + * when VM is started with jmxremote.port=0. + * @library /lib/testlibrary + * @modules java.management/sun.management.jdp + * @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpJmxRemoteDynamicPortTestCase DynamicLauncher + * @run main JdpJmxRemoteDynamicPortTest + */ + +import java.lang.management.ManagementFactory; + +public class JdpJmxRemoteDynamicPortTest extends DynamicLauncher { + final String testName = "JdpJmxRemoteDynamicPortTestCase"; + + public static void main(String[] args) throws Exception { + DynamicLauncher launcher = new JdpJmxRemoteDynamicPortTest(); + launcher.run(); + launcher.getProcessOutpoutAnalyzer().stderrShouldNotContain("java.lang.Exception:"); + } + + protected String[] options() { + String[] options = { + "-Dcom.sun.management.jmxremote.authenticate=false", + "-Dcom.sun.management.jmxremote.ssl=false", + "-Dcom.sun.management.jmxremote=true", + "-Dcom.sun.management.jmxremote.port=0", + "-Dcom.sun.management.jmxremote.autodiscovery=true", + "-Dcom.sun.management.jdp.pause=1", + "-Dcom.sun.management.jdp.name=" + jdpName, + "-Djava.util.logging.SimpleFormatter.format='%1$tF %1$tT %4$-7s %5$s %n'", + testName + }; + return options; + } +} diff --git a/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTestCase.java b/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTestCase.java new file mode 100644 index 00000000000..bb5485ed073 --- /dev/null +++ b/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTestCase.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.net.SocketTimeoutException; +import java.util.Map; + +public class JdpJmxRemoteDynamicPortTestCase extends JdpTestCase { + + private int receivedJDPpackets = 0; + + public JdpJmxRemoteDynamicPortTestCase(ClientConnection connection) { + super(connection); + } + + @Override + protected String initialLogMessage() { + return "Starting test case JdpJmxRemoteDynamicPortTestCase"; + } + + /** + * This method is executed after a correct Jdp packet (coming from this VM) has been received. + * + * @param payload A dictionary containing the Jdp packet data. + */ + protected void packetFromThisVMReceived(Map payload) throws Exception { + receivedJDPpackets++; + final String jmxServiceurl = payload.get("JMX_SERVICE_URL"); + int lastcolon = jmxServiceurl.lastIndexOf(':'); + int nextslash = jmxServiceurl.indexOf('/', lastcolon); + int jmxRemotePort = Integer.parseInt(jmxServiceurl, lastcolon + 1, nextslash, 10); + + log.fine("Received #" + String.valueOf(receivedJDPpackets) + + ", jmxStringUrl=" + jmxServiceurl + ", jmxRemotePort=" + jmxRemotePort); + + if (0 == jmxRemotePort) { + throw new Exception("JmxRemotePort value is zero. Test case failed."); + } + + log.fine("Test case passed"); + } + + /** + * The socket should not timeout. + * It is set to wait for 10 times the defined pause between Jdp packet. See JdpOnTestCase.TIME_OUT_FACTOR. + */ + @Override + protected void onSocketTimeOut(SocketTimeoutException e) throws Exception { + String message = "Timed out waiting for JDP packet. Should arrive within " + + connection.pauseInSeconds + " seconds, but waited for " + + timeOut + " seconds."; + log.severe(message); + throw new Exception(message, e); + } + + + /** + * After receiving one Jdp packets the test should end. + */ + @Override + protected boolean shouldContinue() { + return receivedJDPpackets < 1; + } + + /** + * To run this test manually you might need the following VM options: + *

+ * -Dcom.sun.management.jmxremote.authenticate=false + * -Dcom.sun.management.jmxremote.ssl=false + * -Dcom.sun.management.jmxremote.port=0 + * -Dcom.sun.management.jmxremote=true + * -Dcom.sun.management.jmxremote.autodiscovery=true + * -Dcom.sun.management.jdp.pause=1 + * -Dcom.sun.management.jdp.name=alex (or some other string to identify this VM) + *

+ * Recommended for nice output: + * -Djava.util.logging.SimpleFormatter.format="%1$tF %1$tT %4$-7s %5$s %n" + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + JdpTestCase client = new JdpJmxRemoteDynamicPortTestCase(new ClientConnection()); + client.run(); + } + +}