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:
Dave Syer
2013-11-23 11:26:55 +00:00
parent 59f07d37ab
commit 8efa2fc569
8 changed files with 15 additions and 75 deletions

View File

@@ -82,7 +82,6 @@ public abstract class AbstractEmbeddedServletContainerFactory implements
* @param port the port number for the embedded servlet container
*/
public AbstractEmbeddedServletContainerFactory(int port) {
checkPort(port);
this.port = port;
}
@@ -94,7 +93,6 @@ public abstract class AbstractEmbeddedServletContainerFactory implements
*/
public AbstractEmbeddedServletContainerFactory(String contextPath, int port) {
checkContextPath(contextPath);
checkPort(port);
this.contextPath = contextPath;
this.port = port;
}
@@ -129,16 +127,9 @@ public abstract class AbstractEmbeddedServletContainerFactory implements
@Override
public void setPort(int port) {
checkPort(port);
this.port = port;
}
private void checkPort(int port) {
if (port < 0 || port > 65535) {
throw new IllegalArgumentException("Port must be between 1 and 65535");
}
}
/**
* Returns the port that the embedded servlet container should listen on.
*/

View File

@@ -16,6 +16,8 @@
package org.springframework.boot.context.embedded.jetty;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
@@ -28,10 +30,13 @@ import org.springframework.util.Assert;
* {@link JettyEmbeddedServletContainerFactory} and not directly.
*
* @author Phillip Webb
* @author Dave Syer
* @see JettyEmbeddedServletContainerFactory
*/
public class JettyEmbeddedServletContainer implements EmbeddedServletContainer {
private final Log logger = LogFactory.getLog(JettyEmbeddedServletContainer.class);
private final Server server;
private boolean autoStart;
@@ -81,6 +86,7 @@ public class JettyEmbeddedServletContainer implements EmbeddedServletContainer {
Connector[] connectors = this.server.getConnectors();
for (Connector connector : connectors) {
connector.start();
this.logger.info("Jetty started on port: " + connector.getLocalPort());
}
}
catch (Exception ex) {

View File

@@ -97,7 +97,8 @@ public class JettyEmbeddedServletContainerFactory extends
public EmbeddedServletContainer getEmbeddedServletContainer(
ServletContextInitializer... initializers) {
WebAppContext context = new WebAppContext();
Server server = new Server(new InetSocketAddress(getAddress(), getPort()));
int port = getPort() >= 0 ? getPort() : 0;
Server server = new Server(new InetSocketAddress(getAddress(), port));
if (this.resourceLoader != null) {
context.setClassLoader(this.resourceLoader.getClassLoader());
@@ -123,7 +124,7 @@ public class JettyEmbeddedServletContainerFactory extends
postProcessWebAppContext(context);
server.setHandler(context);
this.logger.info("Server initialized with port: " + getPort());
this.logger.info("Server initialized with port: " + port);
return getJettyEmbeddedServletContainer(server);
}
@@ -241,7 +242,7 @@ public class JettyEmbeddedServletContainerFactory extends
* @return a new {@link JettyEmbeddedServletContainer} instance
*/
protected JettyEmbeddedServletContainer getJettyEmbeddedServletContainer(Server server) {
return new JettyEmbeddedServletContainer(server, getPort() > 0);
return new JettyEmbeddedServletContainer(server, getPort() >= 0);
}
@Override

View File

@@ -104,6 +104,7 @@ public class TomcatEmbeddedServletContainer implements EmbeddedServletContainer
if (connector != null && this.autoStart) {
try {
connector.getProtocolHandler().start();
this.logger.info("Tomcat started on port: " + connector.getLocalPort());
}
catch (Exception ex) {
this.logger.error("Cannot start connector: ", ex);

View File

@@ -193,12 +193,8 @@ public class TomcatEmbeddedServletContainerFactory extends
// Needs to be protected so it can be used by subclasses
protected void customizeConnector(Connector connector) {
if (getPort() > 0) {
connector.setPort(getPort());
}
else {
connector.setPort(8080);
}
int port = getPort() >= 0 ? getPort() : 0;
connector.setPort(port);
if (connector.getProtocolHandler() instanceof AbstractProtocol) {
if (getAddress() != null) {
((AbstractProtocol) connector.getProtocolHandler())
@@ -259,7 +255,7 @@ public class TomcatEmbeddedServletContainerFactory extends
*/
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
return new TomcatEmbeddedServletContainer(tomcat, getPort() > 0);
return new TomcatEmbeddedServletContainer(tomcat, getPort() >= 0);
}
private File createTempDir(String prefix) {