Skip to content

Commit 6df2857

Browse files
authored
fix: respect spring.devtools.livereload.enabled property (#22624)
When developers set spring.devtools.livereload.enabled=false, the application should not attempt to establish a WebSocket connection to the Spring Boot livereload server. This commit fixes the issue by checking the enabled property at the source (SpringDevToolsPortHandler) and propagating the result through the entire chain: - SpringDevToolsPortHandler: Only assigns port if livereload enabled - IndexHtmlRequestHandler: Only includes liveReloadPort in config if set - vaadin-dev-tools.ts: Only creates WebSocket connection if port exists Fixes #22623
1 parent 4c87bac commit 6df2857

File tree

4 files changed

+105
-7
lines changed

4 files changed

+105
-7
lines changed

flow-server/src/main/java/com/vaadin/flow/server/communication/IndexHtmlRequestHandler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ private void addDevTools(Document indexDocument,
396396
Optional<Backend> maybeBackend = liveReload
397397
.map(BrowserLiveReload::getBackend);
398398

399-
int liveReloadPort = Constants.SPRING_BOOT_DEFAULT_LIVE_RELOAD_PORT;
399+
Integer liveReloadPort = null;
400400
VaadinContext context = service.getContext();
401401
if (context instanceof VaadinServletContext vaadinServletContext) {
402402
String customPort = (String) vaadinServletContext.getContext()
@@ -412,7 +412,9 @@ private void addDevTools(Document indexDocument,
412412
BootstrapHandlerHelper.getPushURL(session, request));
413413
maybeBackend.ifPresent(
414414
backend -> devToolsConf.put("backend", backend.toString()));
415-
devToolsConf.put("liveReloadPort", liveReloadPort);
415+
if (liveReloadPort != null) {
416+
devToolsConf.put("liveReloadPort", liveReloadPort);
417+
}
416418
if (isAllowedDevToolsHost(config, request)) {
417419
devToolsConf.put("token", DevToolsToken.getToken());
418420
}

vaadin-dev-server/src/main/frontend/vaadin-dev-tools.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ type DevToolsConf = {
8282
enable: boolean;
8383
url: string;
8484
backend?: string;
85-
liveReloadPort: number;
85+
liveReloadPort?: number;
8686
token?: string;
8787
};
8888

@@ -722,7 +722,7 @@ export class VaadinDevTools extends LitElement {
722722
frontendConnection.onMessage = (message: any) => this.handleFrontendMessage(message);
723723
this.frontendConnection = frontendConnection;
724724

725-
if (this.conf.backend === VaadinDevTools.SPRING_BOOT_DEVTOOLS) {
725+
if (this.conf.backend === VaadinDevTools.SPRING_BOOT_DEVTOOLS && this.conf.liveReloadPort) {
726726
this.javaConnection = new LiveReloadConnection(this.getSpringBootWebSocketUrl(window.location));
727727
this.javaConnection.onHandshake = () => {
728728
if (!VaadinDevTools.isActive) {

vaadin-spring/src/main/java/com/vaadin/flow/spring/SpringDevToolsPortHandler.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,31 @@
2020
import org.springframework.core.env.ConfigurableEnvironment;
2121

2222
import com.vaadin.flow.internal.NetworkUtil;
23+
import com.vaadin.flow.server.Constants;
2324

2425
/**
2526
* Sets Spring Boot dev tools to run on a free random port if the default port
26-
* (35729) is in use.
27+
* is in use.
2728
*/
2829
public class SpringDevToolsPortHandler implements EnvironmentPostProcessor {
2930

3031
private static final String SPRING_DEVTOOLS_LIVERELOAD_PORT = "spring.devtools.livereload.port";
31-
private static final int DEFAULT_PORT = 35729;
32+
private static final String SPRING_DEVTOOLS_LIVERELOAD_ENABLED = "spring.devtools.livereload.enabled";
3233

3334
@Override
3435
public void postProcessEnvironment(ConfigurableEnvironment environment,
3536
SpringApplication application) {
37+
// Only set the port if livereload is enabled (defaults to true when
38+
// DevTools is present)
39+
boolean liveReloadEnabled = environment.getProperty(
40+
SPRING_DEVTOOLS_LIVERELOAD_ENABLED, Boolean.class, true);
41+
42+
if (!liveReloadEnabled) {
43+
return;
44+
}
45+
3646
if (environment.getProperty(SPRING_DEVTOOLS_LIVERELOAD_PORT) == null) {
37-
int reloadPort = DEFAULT_PORT;
47+
int reloadPort = Constants.SPRING_BOOT_DEFAULT_LIVE_RELOAD_PORT;
3848
if (!NetworkUtil.isFreePort(reloadPort)) {
3949
reloadPort = NetworkUtil.getFreePort();
4050
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright 2000-2025 Vaadin Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.vaadin.flow.spring;
17+
18+
import org.junit.Assert;
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
import org.mockito.Mockito;
22+
import org.springframework.boot.SpringApplication;
23+
import org.springframework.core.env.ConfigurableEnvironment;
24+
25+
public class SpringDevToolsPortHandlerTest {
26+
27+
private SpringDevToolsPortHandler handler;
28+
private ConfigurableEnvironment environment;
29+
private SpringApplication application;
30+
31+
@Before
32+
public void setUp() {
33+
handler = new SpringDevToolsPortHandler();
34+
environment = Mockito.mock(ConfigurableEnvironment.class);
35+
application = Mockito.mock(SpringApplication.class);
36+
}
37+
38+
@Test
39+
public void liveReloadEnabled_portIsAssigned() {
40+
// Arrange: livereload enabled (default), no port set
41+
Mockito.when(environment.getProperty(
42+
"spring.devtools.livereload.enabled", Boolean.class, true))
43+
.thenReturn(true);
44+
Mockito.when(environment.getProperty("spring.devtools.livereload.port"))
45+
.thenReturn(null);
46+
47+
// Act
48+
handler.postProcessEnvironment(environment, application);
49+
50+
// Assert: port should be set via System.setProperty
51+
String portProperty = System
52+
.getProperty("spring.devtools.livereload.port");
53+
Assert.assertNotNull("Port should be set when livereload is enabled",
54+
portProperty);
55+
56+
// Verify it's a valid port number
57+
int port = Integer.parseInt(portProperty);
58+
Assert.assertTrue("Port should be positive", port > 0);
59+
Assert.assertTrue("Port should be in valid range", port <= 65535);
60+
61+
// Clean up
62+
System.clearProperty("spring.devtools.livereload.port");
63+
}
64+
65+
@Test
66+
public void liveReloadDisabled_portIsNotAssigned() {
67+
// Arrange: livereload explicitly disabled, no port set
68+
Mockito.when(environment.getProperty(
69+
"spring.devtools.livereload.enabled", Boolean.class, true))
70+
.thenReturn(false);
71+
Mockito.when(environment.getProperty("spring.devtools.livereload.port"))
72+
.thenReturn(null);
73+
74+
// Clear any previously set system property
75+
System.clearProperty("spring.devtools.livereload.port");
76+
77+
// Act
78+
handler.postProcessEnvironment(environment, application);
79+
80+
// Assert: port should NOT be set
81+
String portProperty = System
82+
.getProperty("spring.devtools.livereload.port");
83+
Assert.assertNull("Port should not be set when livereload is disabled",
84+
portProperty);
85+
}
86+
}

0 commit comments

Comments
 (0)