diff --git a/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java b/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java index dc6c05338ea..3c799f6e54d 100644 --- a/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java +++ b/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -82,7 +82,7 @@ public class AllModulesCommandTest implements DebuggeeLauncher.Listener { try { // Establish JDWP socket connection channel = new JdwpChannel(); - channel.connect(); + channel.connect(launcher.getJdwpPort()); // Send out ALLMODULES JDWP command // and verify the reply JdwpAllModulesReply reply = new JdwpAllModulesCmd().send(channel); diff --git a/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java b/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java index 259c9ac0f6c..5c3d01ec2dc 100644 --- a/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java +++ b/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -21,11 +21,9 @@ * questions. */ -import java.io.IOException; -import java.net.ServerSocket; import java.util.StringTokenizer; import jdk.test.lib.JDKToolFinder; -import jdk.test.lib.Utils; +import jdk.test.lib.JDWP; import static jdk.test.lib.Asserts.assertFalse; /** @@ -55,7 +53,7 @@ public class DebuggeeLauncher implements StreamHandler.Listener { void onDebuggeeError(String line); } - private static int jdwpPort = -1; + private int jdwpPort = -1; private static final String CLS_DIR = System.getProperty("test.classes", "").trim(); private static final String DEBUGGEE = "AllModulesCommandTestDebuggee"; private Process p; @@ -117,30 +115,19 @@ public class DebuggeeLauncher implements StreamHandler.Listener { * @return the JDWP options to start the debuggee with */ private static String getJdwpOptions() { - return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + getJdwpPort(); + return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0"; } /** - * Find an available port for the JDWP session + * Gets JDWP port debuggee is listening on. * * @return JDWP port */ - public static int getJdwpPort() { - if (jdwpPort == -1) { - jdwpPort = findFreePort(); - assertFalse(jdwpPort == -1, "Can not find vailbale port for JDWP"); - } + public int getJdwpPort() { + assertFalse(jdwpPort == -1, "JDWP port is not detected"); return jdwpPort; } - private static int findFreePort() { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } catch (IOException e) { - } - return -1; - } - @Override public void onStringRead(StreamHandler handler, String line) { if (handler.equals(errorHandler)) { @@ -152,6 +139,12 @@ public class DebuggeeLauncher implements StreamHandler.Listener { } private void processDebuggeeOutput(String line) { + if (jdwpPort == -1) { + JDWP.ListenAddress addr = JDWP.parseListenAddress(line); + if (addr != null) { + jdwpPort = Integer.parseInt(addr.address()); + } + } StringTokenizer st = new StringTokenizer(line); String token = st.nextToken(); switch (token) { diff --git a/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java b/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java index d2e780c802f..ca27fc52e1e 100644 --- a/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java +++ b/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -33,8 +33,8 @@ public class JdwpChannel { private Socket sock; - public void connect() throws IOException { - sock = new Socket("localhost", DebuggeeLauncher.getJdwpPort()); + public void connect(int jdwpPort) throws IOException { + sock = new Socket("localhost", jdwpPort); handshake(); } diff --git a/test/jdk/com/sun/jdi/JdwpAllowTest.java b/test/jdk/com/sun/jdi/JdwpAllowTest.java index 6fa29ba14ad..a5c756f8790 100644 --- a/test/jdk/com/sun/jdi/JdwpAllowTest.java +++ b/test/jdk/com/sun/jdi/JdwpAllowTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -34,16 +34,14 @@ import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; +import jdk.test.lib.JDWP; import jdk.test.lib.Utils; import jdk.test.lib.apps.LingeredApp; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class JdwpAllowTest { @@ -76,16 +74,14 @@ public class JdwpAllowTest { return new String[] { jdwpArgs }; } - private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(\\d+)\\b"); private static int detectPort(LingeredApp app) { long maxWaitTime = System.currentTimeMillis() + Utils.adjustTimeout(10000); // 10 seconds adjusted for TIMEOUT_FACTOR while (true) { String s = app.getProcessStdout(); - Matcher m = listenRegexp.matcher(s); - if (m.find()) { - // m.group(1) is transport, m.group(2) is port - return Integer.parseInt(m.group(2)); + JDWP.ListenAddress addr = JDWP.parseListenAddress(s); + if (addr != null) { + return Integer.parseInt(addr.address()); } if (System.currentTimeMillis() > maxWaitTime) { throw new RuntimeException("Could not detect port from '" + s + "' (timeout)"); diff --git a/test/jdk/com/sun/jdi/RunToExit.java b/test/jdk/com/sun/jdi/RunToExit.java index b7051b77dbc..d5fd5d2b6f7 100644 --- a/test/jdk/com/sun/jdi/RunToExit.java +++ b/test/jdk/com/sun/jdi/RunToExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2021, 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 @@ -40,9 +40,9 @@ import java.util.Map; import java.util.List; import java.util.Iterator; import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; + +import jdk.test.lib.JDWP; import jdk.test.lib.process.ProcessTools; public class RunToExit { @@ -95,16 +95,12 @@ public class RunToExit { return p; } - /* warm-up predicate for debuggee */ - private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b"); - private static boolean isTransportListening(String line) { - Matcher m = listenRegexp.matcher(line); - if (!m.matches()) { + JDWP.ListenAddress addr = JDWP.parseListenAddress(line); + if (addr == null) { return false; } - // address is 2nd group - address = m.group(2); + address = addr.address(); return true; } diff --git a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java index 71b3eb28d6d..e204b09f713 100644 --- a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java +++ b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -23,6 +23,7 @@ package lib.jdb; +import jdk.test.lib.JDWP; import jdk.test.lib.Utils; import jdk.test.lib.process.ProcessTools; @@ -32,8 +33,6 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -124,24 +123,17 @@ public class Debuggee implements Closeable { // starts the process, waits for "Listening for transport" output and detects transport/address private Debuggee(ProcessBuilder pb, String name) { - // debuggeeListen[0] - transport, debuggeeListen[1] - address - String[] debuggeeListen = new String[2]; - Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b"); + JDWP.ListenAddress[] listenAddress = new JDWP.ListenAddress[1]; try { p = ProcessTools.startProcess(name, pb, s -> output.add(s), // output consumer s -> { // warm-up predicate - Matcher m = listenRegexp.matcher(s); - if (!m.matches()) { - return false; - } - debuggeeListen[0] = m.group(1); - debuggeeListen[1] = m.group(2); - return true; + listenAddress[0] = JDWP.parseListenAddress(s); + return listenAddress[0] != null; }, 30, TimeUnit.SECONDS); - transport = debuggeeListen[0]; - address = debuggeeListen[1]; + transport = listenAddress[0].transport(); + address = listenAddress[0].address(); } catch (IOException | InterruptedException | TimeoutException ex) { throw new RuntimeException("failed to launch debuggee", ex); } diff --git a/test/lib/jdk/test/lib/JDWP.java b/test/lib/jdk/test/lib/JDWP.java new file mode 100644 index 00000000000..2724a1c46a6 --- /dev/null +++ b/test/lib/jdk/test/lib/JDWP.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021, 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. + */ + +package jdk.test.lib; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class JDWP { + + public record ListenAddress(String transport, String address) { + } + + // lazy initialized + private static Pattern listenRegexp; + + /** + * Parses debuggee output to get listening transport and address. + * Returns null if the string specified does not contain required info. + */ + public static ListenAddress parseListenAddress(String debuggeeOutput) { + if (listenRegexp == null) { + listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b"); + } + Matcher m = listenRegexp.matcher(debuggeeOutput); + if (m.find()) { + return new ListenAddress(m.group(1), m.group(2)); + } + return null; + } + +}