diff --git a/test/jdk/com/sun/jdi/JdwpOnThrowTest.java b/test/jdk/com/sun/jdi/JdwpOnThrowTest.java index d083b2a0e84cd..ba3564669b4fe 100644 --- a/test/jdk/com/sun/jdi/JdwpOnThrowTest.java +++ b/test/jdk/com/sun/jdi/JdwpOnThrowTest.java @@ -57,12 +57,11 @@ public class JdwpOnThrowTest { private static AttachingConnector attachingConnector; public static void main(String[] args) throws Exception { - int port = findFreePort(); - try (Debuggee debuggee = Debuggee.launcher("ThrowCaughtException").setAddress("localhost:" + port) - .enableOnThrow("Ex", "Start").setSuspended(true).launch()) { + try (Debuggee debuggee = Debuggee.launcher("ThrowCaughtException") + .enableOnThrow("Ex").setSuspended(true).launch()) { VirtualMachine vm = null; try { - vm = attach("localhost", "" + port); + vm = attach("localhost", debuggee.getAddress()); EventQueue queue = vm.eventQueue(); log("Waiting for exception event"); long start = System.currentTimeMillis(); @@ -110,14 +109,6 @@ private static void verifyExceptionEvent(ExceptionEvent ex) throws Exception { } } - private static int findFreePort() { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - private static VirtualMachine attach(String address, String port) throws IOException { if (attachingConnector == null) { attachingConnector = (AttachingConnector)getConnector(ATTACH_CONNECTOR); diff --git a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java index 709e5f0912a85..35b116d2c51de 100644 --- a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java +++ b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java @@ -33,6 +33,9 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -69,8 +72,7 @@ public static class Launcher { private String address = null; private boolean suspended = true; private String onthrow = ""; - private boolean waitForPortPrint = true; - private String expectedOutputBeforeThrow = ""; + private static final String LAUNCH_ECHO_STRING = "Listen Args:"; private Launcher(String mainClass) { this.mainClass = mainClass; @@ -103,11 +105,8 @@ public Launcher setSuspended(boolean value) { return this; } - // required to pass non null port with address and emit string before the throw - public Launcher enableOnThrow(String value, String expectedOutputBeforeThrow) { - this.onthrow = value; - this.waitForPortPrint = false; - this.expectedOutputBeforeThrow = expectedOutputBeforeThrow; + public Launcher enableOnThrow(String exceptionClassName) { + this.onthrow = exceptionClassName; return this; } @@ -116,7 +115,7 @@ public ProcessBuilder prepare() { if (vmOptions != null) { debuggeeArgs.add(vmOptions); } - String onthrowArgs = onthrow.isEmpty() ? "" : ",onthrow=" + onthrow + ",launch=exit"; + String onthrowArgs = onthrow.isEmpty() ? "" : ",onthrow=" + onthrow + ",launch=echo " + LAUNCH_ECHO_STRING; debuggeeArgs.add("-agentlib:jdwp=transport=" + transport + (address == null ? "" : ",address=" + address) + ",server=y,suspend=" + (suspended ? "y" : "n") @@ -127,33 +126,38 @@ public ProcessBuilder prepare() { } public Debuggee launch(String name) { - return new Debuggee(prepare(), name, waitForPortPrint, expectedOutputBeforeThrow); + return new Debuggee(prepare(), name, + onthrow.isEmpty() ? + JDWP::parseListenAddress : + Launcher::parseLaunchEchoListenAddress + ); } public Debuggee launch() { return launch("debuggee"); } - } - // starts the process, waits for "Listening for transport" output and detects transport/address - private Debuggee(ProcessBuilder pb, String name, boolean waitForPortPrint, String expectedOutputBeforeThrow) { - JDWP.ListenAddress[] listenAddress = new JDWP.ListenAddress[1]; - if (!waitForPortPrint) { - try { - p = ProcessTools.startProcess(name, pb, s -> {output.add(s);}, s -> { - return s.equals(expectedOutputBeforeThrow); - }, 30, TimeUnit.SECONDS); - } catch (IOException | InterruptedException | TimeoutException ex) { - throw new RuntimeException("failed to launch debuggee", ex); + /** + * Parses debuggee output to get listening transport and address, printed by `launch=echo`. + * Returns null if the string specified does not contain required info. + */ + private static JDWP.ListenAddress parseLaunchEchoListenAddress(String debuggeeOutput) { + Pattern listenRegexp = Pattern.compile(LAUNCH_ECHO_STRING + " \\b(.+)\\b \\b(.+)\\b"); + Matcher m = listenRegexp.matcher(debuggeeOutput); + if (m.find()) { + return new JDWP.ListenAddress(m.group(1), m.group(2)); } - transport = null; - address = null; - return; + return null; } + } + + // starts the process, waits until the provided addressDetector detects transport/address from the process output + private Debuggee(ProcessBuilder pb, String name, Function addressDetector) { + JDWP.ListenAddress[] listenAddress = new JDWP.ListenAddress[1]; try { p = ProcessTools.startProcess(name, pb, s -> output.add(s), // output consumer - s -> { // warm-up predicate - listenAddress[0] = JDWP.parseListenAddress(s); + s -> { + listenAddress[0] = addressDetector.apply(s); return listenAddress[0] != null; }, 30, TimeUnit.SECONDS); @@ -211,5 +215,4 @@ public void close() throws IOException { p.destroy(); } } - }