From ec734704c6b5f9f4501c849e56bc0ab8817ee25c Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 7 Jun 2024 09:04:40 +0200 Subject: [PATCH] Make sure we transmit the actual debug port to next dev mode run When starting dev mode, the debug port might not be free and we might use a random one. When restarting dev mode (for instance when you adjust the pom.xml), we should try to reuse this port instead of defaulting to the initially non free one. Also the port being free is tested when we build `DevModeRunner`, so we need to make sure we stop the old runner before build()ing the new instance (and not just before we start the new one). Fixes #40848 --- .../dev/QuarkusDevModeLauncher.java | 22 +++++++------------ .../main/java/io/quarkus/maven/DevMojo.java | 17 ++++++++------ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java index 580506a736255f..d5e2b05b68da44 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java @@ -85,12 +85,6 @@ public B debug(String debug) { return (B) this; } - @SuppressWarnings("unchecked") - public B debugPortOk(Boolean debugPortOk) { - QuarkusDevModeLauncher.this.debugPortOk = debugPortOk; - return (B) this; - } - @SuppressWarnings("unchecked") public B suspend(String suspend) { QuarkusDevModeLauncher.this.suspend = suspend; @@ -303,10 +297,10 @@ public R build() throws Exception { private List args = new ArrayList<>(0); private String debug; - private Boolean debugPortOk; private String suspend; private String debugHost = "localhost"; private String debugPort = "5005"; + private String actualDebugPort; private File projectDir; private File buildDir; private File outputDir; @@ -390,12 +384,13 @@ protected void prepare() throws Exception { if (debug != null && debug.equalsIgnoreCase("client")) { args.add("-agentlib:jdwp=transport=dt_socket,address=" + debugHost + ":" + port + ",server=n,suspend=" + suspend); + actualDebugPort = String.valueOf(port); } else if (debug == null || !debug.equalsIgnoreCase("false")) { // if the debug port is used, we want to make an effort to pick another one // if we can't find an open port, we don't fail the process launch, we just don't enable debugging // Furthermore, we don't check this on restarts, as the previous process is still running boolean warnAboutChange = false; - if (debugPortOk == null) { + if (actualDebugPort == null) { int tries = 0; while (true) { boolean isPortUsed; @@ -408,20 +403,19 @@ protected void prepare() throws Exception { isPortUsed = false; } if (!isPortUsed) { - debugPortOk = true; + actualDebugPort = String.valueOf(port); break; } if (++tries >= 5) { - debugPortOk = false; break; } else { port = getRandomPort(); } } } - if (debugPortOk) { + if (actualDebugPort != null) { if (warnAboutChange) { - warn("Changed debug port to " + port + " because of a port conflict"); + warn("Changed debug port to " + actualDebugPort + " because of a port conflict"); } args.add("-agentlib:jdwp=transport=dt_socket,address=" + debugHost + ":" + port + ",server=y,suspend=" + suspend); @@ -547,8 +541,8 @@ public List args() { return args; } - public Boolean getDebugPortOk() { - return debugPortOk; + public String getActualDebugPort() { + return actualDebugPort; } protected abstract boolean isDebugEnabled(); diff --git a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java index 29b240034af539..d1aa33d56f2e90 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java @@ -478,15 +478,19 @@ public void close() throws IOException { } if (!changed.isEmpty()) { getLog().info("Changes detected to " + changed + ", restarting dev mode"); + + // stop the runner before we build the new one as the debug port being free + // is tested when building the runner + runner.stop(); + final DevModeRunner newRunner; try { bootstrapId = handleAutoCompile(); - newRunner = new DevModeRunner(runner.launcher.getDebugPortOk(), bootstrapId); + newRunner = new DevModeRunner(runner.launcher.getActualDebugPort(), bootstrapId); } catch (Exception e) { getLog().info("Could not load changed pom.xml file, changes not applied", e); continue; } - runner.stop(); newRunner.run(); runner = newRunner; } @@ -1171,8 +1175,8 @@ private DevModeRunner(String bootstrapId) throws Exception { launcher = newLauncher(null, bootstrapId); } - private DevModeRunner(Boolean debugPortOk, String bootstrapId) throws Exception { - launcher = newLauncher(debugPortOk, bootstrapId); + private DevModeRunner(String actualDebugPort, String bootstrapId) throws Exception { + launcher = newLauncher(actualDebugPort, bootstrapId); } Collection pomFiles() { @@ -1226,7 +1230,7 @@ void stop() throws InterruptedException { } } - private QuarkusDevModeLauncher newLauncher(Boolean debugPortOk, String bootstrapId) throws Exception { + private QuarkusDevModeLauncher newLauncher(String actualDebugPort, String bootstrapId) throws Exception { String java = null; // See if a toolchain is configured if (toolchainManager != null) { @@ -1244,8 +1248,7 @@ private QuarkusDevModeLauncher newLauncher(Boolean debugPortOk, String bootstrap .suspend(suspend) .debug(debug) .debugHost(debugHost) - .debugPort(debugPort) - .debugPortOk(debugPortOk) + .debugPort(actualDebugPort) .deleteDevJar(deleteDevJar); setJvmArgs(builder);