Skip to content

Commit 685a195

Browse files
committed
Deprecate SocketUtils
SocketUtils was introduced in Spring Framework 4.0, primarily to assist in writing integration tests which start an external server on an available random port. However, these utilities make no guarantee about the subsequent availability of a given port and are therefore unreliable. Instead of using SocketUtils to find an available local port for a server, it is recommended that users rely on a server's ability to start on a random port that it selects or is assigned by the operating system. To interact with that server, the user should query the server for the port it is currently using. SocketUtils is now deprecated in 5.3.16 and will be removed in 6.0. Closes gh-28052
1 parent 3188c0f commit 685a195

File tree

10 files changed

+69
-56
lines changed

10 files changed

+69
-56
lines changed

spring-context/src/test/java/org/springframework/jmx/access/MBeanClientInterceptorTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -39,7 +39,6 @@
3939
import org.springframework.jmx.JmxTestBean;
4040
import org.springframework.jmx.export.MBeanExporter;
4141
import org.springframework.jmx.export.assembler.AbstractReflectiveMBeanInfoAssembler;
42-
import org.springframework.util.SocketUtils;
4342

4443
import static org.assertj.core.api.Assertions.assertThat;
4544
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -177,7 +176,8 @@ void invokeUnexposedMethodWithException() throws Exception {
177176
void lazyConnectionToRemote() throws Exception {
178177
assumeTrue(runTests);
179178

180-
final int port = SocketUtils.findAvailableTcpPort();
179+
@SuppressWarnings("deprecation")
180+
final int port = org.springframework.util.SocketUtils.findAvailableTcpPort();
181181

182182
JMXServiceURL url = new JMXServiceURL("service:jmx:jmxmp://localhost:" + port);
183183
JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer());

spring-context/src/test/java/org/springframework/jmx/access/RemoteMBeanClientInterceptorTests.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -28,16 +28,15 @@
2828

2929
import org.junit.jupiter.api.AfterEach;
3030

31-
import org.springframework.util.SocketUtils;
32-
3331
/**
3432
* @author Rob Harrop
3533
* @author Chris Beams
3634
* @author Sam Brannen
3735
*/
3836
class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests {
3937

40-
private final int servicePort = SocketUtils.findAvailableTcpPort();
38+
@SuppressWarnings("deprecation")
39+
private final int servicePort = org.springframework.util.SocketUtils.findAvailableTcpPort();
4140

4241
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + servicePort;
4342

spring-context/src/test/java/org/springframework/jmx/support/ConnectorServerFactoryBeanTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -31,7 +31,6 @@
3131
import org.junit.jupiter.api.Test;
3232

3333
import org.springframework.jmx.AbstractMBeanServerTests;
34-
import org.springframework.util.SocketUtils;
3534

3635
import static org.assertj.core.api.Assertions.assertThat;
3736
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -47,7 +46,8 @@ class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
4746

4847
private static final String OBJECT_NAME = "spring:type=connector,name=test";
4948

50-
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + SocketUtils.findAvailableTcpPort();
49+
@SuppressWarnings("deprecation")
50+
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + org.springframework.util.SocketUtils.findAvailableTcpPort();
5151

5252

5353
@Test

spring-context/src/test/java/org/springframework/jmx/support/MBeanServerConnectionFactoryBeanTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -25,7 +25,6 @@
2525

2626
import org.springframework.aop.support.AopUtils;
2727
import org.springframework.jmx.AbstractMBeanServerTests;
28-
import org.springframework.util.SocketUtils;
2928

3029
import static org.assertj.core.api.Assertions.assertThat;
3130
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -39,7 +38,8 @@
3938
*/
4039
class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTests {
4140

42-
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + SocketUtils.findAvailableTcpPort();
41+
@SuppressWarnings("deprecation")
42+
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + org.springframework.util.SocketUtils.findAvailableTcpPort();
4343

4444

4545
@Test

spring-core/src/main/java/org/springframework/util/SocketUtils.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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,13 +32,25 @@
3232
* <p>Within this class, a TCP port refers to a port for a {@link ServerSocket};
3333
* whereas, a UDP port refers to a port for a {@link DatagramSocket}.
3434
*
35+
* <p>{@code SocketUtils} was introduced in Spring Framework 4.0, primarily to
36+
* assist in writing integration tests which start an external server on an
37+
* available random port. However, these utilities make no guarantee about the
38+
* subsequent availability of a given port and are therefore unreliable. Instead
39+
* of using {@code SocketUtils} to find an available local port for a server, it
40+
* is recommended that you rely on a server's ability to start on a random port
41+
* that it selects or is assigned by the operating system. To interact with that
42+
* server, you should query the server for the port it is currently using.
43+
*
3544
* @author Sam Brannen
3645
* @author Ben Hale
3746
* @author Arjen Poutsma
3847
* @author Gunnar Hillert
3948
* @author Gary Russell
4049
* @since 4.0
50+
* @deprecated as of Spring Framework 5.3.16, to be removed in 6.0; see
51+
* {@link SocketUtils class-level Javadoc} for details.
4152
*/
53+
@Deprecated
4254
public class SocketUtils {
4355

4456
/**

spring-core/src/test/java/org/springframework/util/SocketUtilsTests.java

+33-30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -28,76 +28,76 @@
2828
import static org.assertj.core.api.Assertions.assertThat;
2929
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3030
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
31-
import static org.springframework.util.SocketUtils.PORT_RANGE_MAX;
32-
import static org.springframework.util.SocketUtils.PORT_RANGE_MIN;
3331

3432
/**
3533
* Unit tests for {@link SocketUtils}.
3634
*
3735
* @author Sam Brannen
3836
* @author Gary Russell
3937
*/
38+
@SuppressWarnings("deprecation")
4039
class SocketUtilsTests {
4140

4241
@Test
4342
void canBeInstantiated() {
4443
// Just making sure somebody doesn't try to make SocketUtils abstract,
4544
// since that would be a breaking change due to the intentional public
4645
// constructor.
47-
new SocketUtils();
46+
new org.springframework.util.SocketUtils();
4847
}
4948

5049
// TCP
5150

5251
@Test
5352
void findAvailableTcpPortWithZeroMinPort() {
5453
assertThatIllegalArgumentException().isThrownBy(() ->
55-
SocketUtils.findAvailableTcpPort(0));
54+
org.springframework.util.SocketUtils.findAvailableTcpPort(0));
5655
}
5756

5857
@Test
5958
void findAvailableTcpPortWithNegativeMinPort() {
6059
assertThatIllegalArgumentException().isThrownBy(() ->
61-
SocketUtils.findAvailableTcpPort(-500));
60+
org.springframework.util.SocketUtils.findAvailableTcpPort(-500));
6261
}
6362

6463
@Test
6564
void findAvailableTcpPort() {
66-
int port = SocketUtils.findAvailableTcpPort();
67-
assertPortInRange(port, PORT_RANGE_MIN, PORT_RANGE_MAX);
65+
int port = org.springframework.util.SocketUtils.findAvailableTcpPort();
66+
assertPortInRange(port, org.springframework.util.SocketUtils.PORT_RANGE_MIN,
67+
org.springframework.util.SocketUtils.PORT_RANGE_MAX);
6868
}
6969

7070
@Test
7171
void findAvailableTcpPortWithMinPortEqualToMaxPort() {
72-
int minMaxPort = SocketUtils.findAvailableTcpPort();
73-
int port = SocketUtils.findAvailableTcpPort(minMaxPort, minMaxPort);
72+
int minMaxPort = org.springframework.util.SocketUtils.findAvailableTcpPort();
73+
int port = org.springframework.util.SocketUtils.findAvailableTcpPort(minMaxPort, minMaxPort);
7474
assertThat(port).isEqualTo(minMaxPort);
7575
}
7676

7777
@Test
7878
void findAvailableTcpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception {
79-
int port = SocketUtils.findAvailableTcpPort();
79+
int port = org.springframework.util.SocketUtils.findAvailableTcpPort();
8080
try (ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName("localhost"))) {
8181
assertThat(socket).isNotNull();
8282
// will only look for the exact port
8383
assertThatIllegalStateException().isThrownBy(() ->
84-
SocketUtils.findAvailableTcpPort(port, port))
84+
org.springframework.util.SocketUtils.findAvailableTcpPort(port, port))
8585
.withMessageStartingWith("Could not find an available TCP port")
8686
.withMessageEndingWith("after 1 attempts");
8787
}
8888
}
8989

9090
@Test
9191
void findAvailableTcpPortWithMin() {
92-
int port = SocketUtils.findAvailableTcpPort(50000);
93-
assertPortInRange(port, 50000, PORT_RANGE_MAX);
92+
int port = org.springframework.util.SocketUtils.findAvailableTcpPort(50000);
93+
assertPortInRange(port, 50000, org.springframework.util.SocketUtils.PORT_RANGE_MAX);
9494
}
9595

9696
@Test
9797
void findAvailableTcpPortInRange() {
9898
int minPort = 20000;
9999
int maxPort = minPort + 1000;
100-
int port = SocketUtils.findAvailableTcpPort(minPort, maxPort);
100+
int port = org.springframework.util.SocketUtils.findAvailableTcpPort(minPort, maxPort);
101101
assertPortInRange(port, minPort, maxPort);
102102
}
103103

@@ -133,45 +133,46 @@ void findAvailableTcpPortsWithRequestedNumberGreaterThanSizeOfRange() {
133133
@Test
134134
void findAvailableUdpPortWithZeroMinPort() {
135135
assertThatIllegalArgumentException().isThrownBy(() ->
136-
SocketUtils.findAvailableUdpPort(0));
136+
org.springframework.util.SocketUtils.findAvailableUdpPort(0));
137137
}
138138

139139
@Test
140140
void findAvailableUdpPortWithNegativeMinPort() {
141141
assertThatIllegalArgumentException().isThrownBy(() ->
142-
SocketUtils.findAvailableUdpPort(-500));
142+
org.springframework.util.SocketUtils.findAvailableUdpPort(-500));
143143
}
144144

145145
@Test
146146
void findAvailableUdpPort() {
147-
int port = SocketUtils.findAvailableUdpPort();
148-
assertPortInRange(port, PORT_RANGE_MIN, PORT_RANGE_MAX);
147+
int port = org.springframework.util.SocketUtils.findAvailableUdpPort();
148+
assertPortInRange(port, org.springframework.util.SocketUtils.PORT_RANGE_MIN,
149+
org.springframework.util.SocketUtils.PORT_RANGE_MAX);
149150
}
150151

151152
@Test
152153
void findAvailableUdpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception {
153-
int port = SocketUtils.findAvailableUdpPort();
154+
int port = org.springframework.util.SocketUtils.findAvailableUdpPort();
154155
try (DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost"))) {
155156
assertThat(socket).isNotNull();
156157
// will only look for the exact port
157158
assertThatIllegalStateException().isThrownBy(() ->
158-
SocketUtils.findAvailableUdpPort(port, port))
159+
org.springframework.util.SocketUtils.findAvailableUdpPort(port, port))
159160
.withMessageStartingWith("Could not find an available UDP port")
160161
.withMessageEndingWith("after 1 attempts");
161162
}
162163
}
163164

164165
@Test
165166
void findAvailableUdpPortWithMin() {
166-
int port = SocketUtils.findAvailableUdpPort(50000);
167-
assertPortInRange(port, 50000, PORT_RANGE_MAX);
167+
int port = org.springframework.util.SocketUtils.findAvailableUdpPort(50000);
168+
assertPortInRange(port, 50000, org.springframework.util.SocketUtils.PORT_RANGE_MAX);
168169
}
169170

170171
@Test
171172
void findAvailableUdpPortInRange() {
172173
int minPort = 20000;
173174
int maxPort = minPort + 1000;
174-
int port = SocketUtils.findAvailableUdpPort(minPort, maxPort);
175+
int port = org.springframework.util.SocketUtils.findAvailableUdpPort(minPort, maxPort);
175176
assertPortInRange(port, minPort, maxPort);
176177
}
177178

@@ -205,22 +206,24 @@ void findAvailableUdpPortsWithRequestedNumberGreaterThanSizeOfRange() {
205206
// Helpers
206207

207208
private void findAvailableTcpPorts(int numRequested) {
208-
SortedSet<Integer> ports = SocketUtils.findAvailableTcpPorts(numRequested);
209-
assertAvailablePorts(ports, numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX);
209+
SortedSet<Integer> ports = org.springframework.util.SocketUtils.findAvailableTcpPorts(numRequested);
210+
assertAvailablePorts(ports, numRequested, org.springframework.util.SocketUtils.PORT_RANGE_MIN,
211+
org.springframework.util.SocketUtils.PORT_RANGE_MAX);
210212
}
211213

212214
private void findAvailableTcpPorts(int numRequested, int minPort, int maxPort) {
213-
SortedSet<Integer> ports = SocketUtils.findAvailableTcpPorts(numRequested, minPort, maxPort);
215+
SortedSet<Integer> ports = org.springframework.util.SocketUtils.findAvailableTcpPorts(numRequested, minPort, maxPort);
214216
assertAvailablePorts(ports, numRequested, minPort, maxPort);
215217
}
216218

217219
private void findAvailableUdpPorts(int numRequested) {
218-
SortedSet<Integer> ports = SocketUtils.findAvailableUdpPorts(numRequested);
219-
assertAvailablePorts(ports, numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX);
220+
SortedSet<Integer> ports = org.springframework.util.SocketUtils.findAvailableUdpPorts(numRequested);
221+
assertAvailablePorts(ports, numRequested, org.springframework.util.SocketUtils.PORT_RANGE_MIN,
222+
org.springframework.util.SocketUtils.PORT_RANGE_MAX);
220223
}
221224

222225
private void findAvailableUdpPorts(int numRequested, int minPort, int maxPort) {
223-
SortedSet<Integer> ports = SocketUtils.findAvailableUdpPorts(numRequested, minPort, maxPort);
226+
SortedSet<Integer> ports = org.springframework.util.SocketUtils.findAvailableUdpPorts(numRequested, minPort, maxPort);
224227
assertAvailablePorts(ports, numRequested, minPort, maxPort);
225228
}
226229
private void assertPortInRange(int port, int minPort, int maxPort) {

spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClientTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -36,7 +36,6 @@
3636
import org.springframework.messaging.simp.stomp.StompSession.Subscription;
3737
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
3838
import org.springframework.util.Assert;
39-
import org.springframework.util.SocketUtils;
4039
import org.springframework.util.concurrent.ListenableFuture;
4140

4241
import static org.assertj.core.api.Assertions.assertThat;
@@ -61,7 +60,8 @@ public class ReactorNettyTcpStompClientTests {
6160
public void setup(TestInfo testInfo) throws Exception {
6261
logger.debug("Setting up before '" + testInfo.getTestMethod().get().getName() + "'");
6362

64-
int port = SocketUtils.findAvailableTcpPort(61613);
63+
@SuppressWarnings("deprecation")
64+
int port = org.springframework.util.SocketUtils.findAvailableTcpPort(61613);
6565

6666
this.activeMQBroker = new BrokerService();
6767
this.activeMQBroker.addConnector("stomp://127.0.0.1:" + port);

spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerIntegrationTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -46,7 +46,6 @@
4646
import org.springframework.messaging.support.ExecutorSubscribableChannel;
4747
import org.springframework.messaging.support.MessageBuilder;
4848
import org.springframework.util.Assert;
49-
import org.springframework.util.SocketUtils;
5049

5150
import static org.assertj.core.api.Assertions.assertThat;
5251
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -75,10 +74,11 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
7574

7675

7776
@BeforeEach
77+
@SuppressWarnings("deprecation")
7878
public void setup(TestInfo testInfo) throws Exception {
7979
logger.debug("Setting up before '" + testInfo.getTestMethod().get().getName() + "'");
8080

81-
this.port = SocketUtils.findAvailableTcpPort(61613);
81+
this.port = org.springframework.util.SocketUtils.findAvailableTcpPort(61613);
8282
this.responseChannel = new ExecutorSubscribableChannel();
8383
this.responseHandler = new TestMessageHandler();
8484
this.responseChannel.subscribe(this.responseHandler);

spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -27,7 +27,6 @@
2727
import org.springframework.beans.testfixture.beans.ITestBean;
2828
import org.springframework.beans.testfixture.beans.TestBean;
2929
import org.springframework.remoting.RemoteAccessException;
30-
import org.springframework.util.SocketUtils;
3130

3231
import static org.assertj.core.api.Assertions.assertThat;
3332
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -109,7 +108,7 @@ public void hessianProxyFactoryBeanWithCustomProxyFactory() throws Exception {
109108
@Test
110109
@SuppressWarnings("deprecation")
111110
public void simpleHessianServiceExporter() throws IOException {
112-
final int port = SocketUtils.findAvailableTcpPort();
111+
final int port = org.springframework.util.SocketUtils.findAvailableTcpPort();
113112

114113
TestBean tb = new TestBean("tb");
115114
SimpleHessianServiceExporter exporter = new SimpleHessianServiceExporter();

0 commit comments

Comments
 (0)