Skip to content

Commit 03a9738

Browse files
committed
Merge branch '2.2.x'
Closes gh-21053
2 parents 5d56d65 + 7d68c7c commit 03a9738

File tree

6 files changed

+35
-9
lines changed

6 files changed

+35
-9
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyWebServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public void start() throws WebServerException {
175175
}
176176
catch (IOException ex) {
177177
if (connector instanceof NetworkConnector && findBindException(ex) != null) {
178-
throw new PortInUseException(((NetworkConnector) connector).getPort());
178+
throw new PortInUseException(((NetworkConnector) connector).getPort(), ex);
179179
}
180180
throw ex;
181181
}

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyWebServer.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.function.Predicate;
2424

2525
import io.netty.channel.group.DefaultChannelGroup;
26+
import io.netty.channel.unix.Errors.NativeIoException;
2627
import io.netty.util.concurrent.DefaultEventExecutor;
2728
import org.apache.commons.logging.Log;
2829
import org.apache.commons.logging.LogFactory;
@@ -53,7 +54,12 @@
5354
*/
5455
public class NettyWebServer implements WebServer {
5556

56-
private static final Predicate<HttpServerRequest> ALWAYS = (r) -> true;
57+
/**
58+
* Permission denied error code from {@code errno.h}.
59+
*/
60+
private static final int ERROR_NO_EACCES = -13;
61+
62+
private static final Predicate<HttpServerRequest> ALWAYS = (request) -> true;
5763

5864
private static final Log logger = LogFactory.getLog(NettyWebServer.class);
5965

@@ -111,8 +117,8 @@ public void start() throws WebServerException {
111117
}
112118
catch (Exception ex) {
113119
ChannelBindException bindException = findBindException(ex);
114-
if (bindException != null) {
115-
throw new PortInUseException(bindException.localPort());
120+
if (bindException != null && !isPermissionDenied(bindException.getCause())) {
121+
throw new PortInUseException(bindException.localPort(), ex);
116122
}
117123
throw new WebServerException("Unable to start Netty", ex);
118124
}
@@ -121,6 +127,17 @@ public void start() throws WebServerException {
121127
}
122128
}
123129

130+
private boolean isPermissionDenied(Throwable bindExceptionCause) {
131+
try {
132+
if (bindExceptionCause instanceof NativeIoException) {
133+
return ((NativeIoException) bindExceptionCause).expectedErr() == ERROR_NO_EACCES;
134+
}
135+
}
136+
catch (Throwable ex) {
137+
}
138+
return false;
139+
}
140+
124141
@Override
125142
public boolean shutDownGracefully() {
126143
return this.shutdown.shutDownGracefully();

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public void start() throws WebServerException {
178178
List<Port> actualPorts = getActualPorts();
179179
failedPorts.removeAll(actualPorts);
180180
if (failedPorts.size() == 1) {
181-
throw new PortInUseException(failedPorts.iterator().next().getNumber());
181+
throw new PortInUseException(failedPorts.iterator().next().getNumber(), ex);
182182
}
183183
}
184184
throw new WebServerException("Unable to start embedded Undertow", ex);

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public void start() throws WebServerException {
126126
List<UndertowWebServer.Port> actualPorts = getActualPorts();
127127
failedPorts.removeAll(actualPorts);
128128
if (failedPorts.size() == 1) {
129-
throw new PortInUseException(failedPorts.iterator().next().getNumber());
129+
throw new PortInUseException(failedPorts.iterator().next().getNumber(), ex);
130130
}
131131
}
132132
throw new WebServerException("Unable to start embedded Undertow", ex);

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PortInUseException.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,7 +32,16 @@ public class PortInUseException extends WebServerException {
3232
* @param port the port that was in use
3333
*/
3434
public PortInUseException(int port) {
35-
super("Port " + port + " is already in use", null);
35+
this(port, null);
36+
}
37+
38+
/**
39+
* Creates a new port in use exception for the given {@code port}.
40+
* @param port the port that was in use
41+
* @param cause the cause of the exception
42+
*/
43+
public PortInUseException(int port, Throwable cause) {
44+
super("Port " + port + " is already in use", cause);
3645
this.port = port;
3746
}
3847

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactoryTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void exceptionIsThrownWhenPortIsAlreadyInUse() {
6666
this.webServer.start();
6767
factory.setPort(this.webServer.getPort());
6868
assertThatExceptionOfType(PortInUseException.class).isThrownBy(factory.getWebServer(new EchoHandler())::start)
69-
.satisfies(this::portMatchesRequirement);
69+
.satisfies(this::portMatchesRequirement).withCauseInstanceOf(Throwable.class);
7070
}
7171

7272
private void portMatchesRequirement(PortInUseException exception) {

0 commit comments

Comments
 (0)