Use server.port=0 for scanning
This leverages existing capabilities of teh JDK and the OS to grab a port at random and not have it stolen by another process. It's very hard to avoid that race condition in pure Java code, so why bother? User can set port<0 to disable autoStart of connectors (e.g. to start a web application context but not have it listen on any port). In that case the actual socket port will be set to 0 (and therefore if it ever starts up the local port will be random).
This commit is contained in:
@@ -35,7 +35,6 @@ import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomize
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.SocketUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -54,8 +53,6 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
|
||||
private Integer sessionTimeout;
|
||||
|
||||
private boolean scan = false;
|
||||
|
||||
@NotNull
|
||||
private String contextPath = "";
|
||||
|
||||
@@ -81,14 +78,6 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public boolean getScan() {
|
||||
return this.scan;
|
||||
}
|
||||
|
||||
public void setScan(boolean scan) {
|
||||
this.scan = scan;
|
||||
}
|
||||
|
||||
public InetAddress getAddress() {
|
||||
return this.address;
|
||||
}
|
||||
@@ -112,9 +101,6 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
@Override
|
||||
public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
|
||||
Integer port = getPort();
|
||||
if (this.scan) {
|
||||
port = scanForPort(port);
|
||||
}
|
||||
if (port != null) {
|
||||
factory.setPort(port);
|
||||
}
|
||||
@@ -132,26 +118,6 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
}
|
||||
}
|
||||
|
||||
private Integer scanForPort(Integer port) {
|
||||
boolean found = false;
|
||||
int delta = 1;
|
||||
port = port == null ? 8080 : port;
|
||||
while (!found) {
|
||||
try {
|
||||
port = SocketUtils.findAvailableTcpPort(port, port + delta);
|
||||
found = true;
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
if (delta > 65536) {
|
||||
throw e;
|
||||
}
|
||||
delta = delta > 5 ? delta > 100 ? delta * 4 : delta * 3 : delta * 2;
|
||||
}
|
||||
port = port + delta;
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
public static class Tomcat {
|
||||
|
||||
private String accessLogPattern;
|
||||
|
||||
@@ -24,12 +24,9 @@ import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.boot.bind.RelaxedDataBinder;
|
||||
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link ServerProperties}.
|
||||
@@ -71,24 +68,6 @@ public class ServerPropertiesTests {
|
||||
.getProtocolHeader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPortScan() throws Exception {
|
||||
this.properties.setScan(true);
|
||||
this.properties.setPort(1000);
|
||||
ConfigurableEmbeddedServletContainerFactory factory = new MockEmbeddedServletContainerFactory();
|
||||
this.properties.customize(factory);
|
||||
assertTrue(factory.getPort() > 1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPortScanFromHigher() throws Exception {
|
||||
this.properties.setScan(true);
|
||||
this.properties.setPort(5678);
|
||||
ConfigurableEmbeddedServletContainerFactory factory = new MockEmbeddedServletContainerFactory();
|
||||
this.properties.customize(factory);
|
||||
assertTrue(factory.getPort() < 6000);
|
||||
}
|
||||
|
||||
// FIXME test customize
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user