diff --git a/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForConflicts.java b/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForConflicts.java index 0396522e127..0628362345c 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForConflicts.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForConflicts.java @@ -34,6 +34,7 @@ import java.util.function.Predicate; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; @@ -68,8 +69,10 @@ public class CheckClasspathForConflicts extends DefaultTask { for (File file : this.classpath) { if (file.isDirectory()) { Path root = file.toPath(); - Files.walk(root).filter(Files::isRegularFile) - .forEach((entry) -> classpathContents.add(root.relativize(entry).toString(), root.toString())); + try (Stream pathStream = Files.walk(root)) { + pathStream.filter(Files::isRegularFile).forEach( + (entry) -> classpathContents.add(root.relativize(entry).toString(), root.toString())); + } } else { try (JarFile jar = new JarFile(file)) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java index 2a46639c3bd..c7ea9beeed7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java @@ -178,11 +178,15 @@ class RabbitAutoConfigurationTests { com.rabbitmq.client.ConnectionFactory rcf = mock(com.rabbitmq.client.ConnectionFactory.class); given(rcf.newConnection(isNull(), eq(addresses), anyString())).willReturn(mock(Connection.class)); ReflectionTestUtils.setField(connectionFactory, "rabbitConnectionFactory", rcf); - connectionFactory.createConnection(); - then(rcf).should().newConnection(isNull(), eq(addresses), eq("test#0")); + try (org.springframework.amqp.rabbit.connection.Connection connection = connectionFactory + .createConnection()) { + then(rcf).should().newConnection(isNull(), eq(addresses), eq("test#0")); + } connectionFactory.resetConnection(); - connectionFactory.createConnection(); - then(rcf).should().newConnection(isNull(), eq(addresses), eq("test#1")); + try (org.springframework.amqp.rabbit.connection.Connection connection = connectionFactory + .createConnection()) { + then(rcf).should().newConnection(isNull(), eq(addresses), eq("test#1")); + } }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfigurationTests.java index 1c5ae5a94c3..eacad1065e5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfigurationTests.java @@ -205,8 +205,9 @@ class MultipartAutoConfigurationTests { HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); ClientHttpRequest request = requestFactory.createRequest( new URI("http://localhost:" + this.context.getWebServer().getPort() + "/"), HttpMethod.GET); - ClientHttpResponse response = request.execute(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + try (ClientHttpResponse response = request.execute()) { + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + } } private void verifyServletWorks() { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java index eba32e8aa71..3321414228b 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java @@ -111,7 +111,7 @@ public class DevToolsDataSourceAutoConfiguration { DERBY(null, new HashSet<>(Arrays.asList("org.apache.derby.jdbc.EmbeddedDriver")), (dataSource) -> { String url = dataSource.getConnection().getMetaData().getURL(); try { - new EmbeddedDriver().connect(url + ";drop=true", new Properties()); + new EmbeddedDriver().connect(url + ";drop=true", new Properties()).close(); } catch (SQLException ex) { if (!"08006".equals(ex.getSQLState())) { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java index 1fc921daf86..8cfe3144db9 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java @@ -110,10 +110,11 @@ public class ClassPathChangeUploader implements ApplicationListener "Unexpected " + statusCode + " response uploading class files"); + try (ClientHttpResponse response = request.execute()) { + HttpStatusCode statusCode = response.getStatusCode(); + Assert.state(statusCode == HttpStatus.OK, + () -> "Unexpected " + statusCode + " response uploading class files"); + } return; } catch (SocketException ex) { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/DelayedLiveReloadTrigger.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/DelayedLiveReloadTrigger.java index 1328b183286..6408535b293 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/DelayedLiveReloadTrigger.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/DelayedLiveReloadTrigger.java @@ -103,8 +103,9 @@ class DelayedLiveReloadTrigger implements Runnable { private boolean isUp() { try { ClientHttpRequest request = createRequest(); - ClientHttpResponse response = request.execute(); - return response.getStatusCode() == HttpStatus.OK; + try (ClientHttpResponse response = request.execute()) { + return response.getStatusCode() == HttpStatus.OK; + } } catch (Exception ex) { return false; diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/client/HttpTunnelConnectionTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/client/HttpTunnelConnectionTests.java index f3e214a2267..2315cda42ba 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/client/HttpTunnelConnectionTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/client/HttpTunnelConnectionTests.java @@ -139,9 +139,10 @@ class HttpTunnelConnectionTests { @Test void connectFailureLogsWarning(CapturedOutput output) throws Exception { this.requestFactory.willRespond(new ConnectException()); - TunnelChannel tunnel = openTunnel(true); - assertThat(tunnel.isOpen()).isFalse(); - assertThat(output).contains("Failed to connect to remote application at http://localhost:12345"); + try (TunnelChannel tunnel = openTunnel(true)) { + assertThat(tunnel.isOpen()).isFalse(); + assertThat(output).contains("Failed to connect to remote application at http://localhost:12345"); + } } private void write(TunnelChannel channel, String string) throws IOException { diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/server/SocketTargetServerConnectionTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/server/SocketTargetServerConnectionTests.java index 0d619f5c20b..d822cc8aa01 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/server/SocketTargetServerConnectionTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/tunnel/server/SocketTargetServerConnectionTests.java @@ -53,34 +53,37 @@ class SocketTargetServerConnectionTests { void readData() throws Exception { this.server.willSend("hello".getBytes()); this.server.start(); - ByteChannel channel = this.connection.open(DEFAULT_TIMEOUT); - ByteBuffer buffer = ByteBuffer.allocate(5); - channel.read(buffer); - assertThat(buffer.array()).isEqualTo("hello".getBytes()); + try (ByteChannel channel = this.connection.open(DEFAULT_TIMEOUT)) { + ByteBuffer buffer = ByteBuffer.allocate(5); + channel.read(buffer); + assertThat(buffer.array()).isEqualTo("hello".getBytes()); + } } @Test void writeData() throws Exception { this.server.expect("hello".getBytes()); this.server.start(); - ByteChannel channel = this.connection.open(DEFAULT_TIMEOUT); - ByteBuffer buffer = ByteBuffer.wrap("hello".getBytes()); - channel.write(buffer); - this.server.closeAndVerify(); + try (ByteChannel channel = this.connection.open(DEFAULT_TIMEOUT)) { + ByteBuffer buffer = ByteBuffer.wrap("hello".getBytes()); + channel.write(buffer); + this.server.closeAndVerify(); + } } @Test void timeout() throws Exception { this.server.delay(1000); this.server.start(); - ByteChannel channel = this.connection.open(10); - long startTime = System.currentTimeMillis(); - assertThatExceptionOfType(SocketTimeoutException.class).isThrownBy(() -> channel.read(ByteBuffer.allocate(5))) - .satisfies((ex) -> { - long runTime = System.currentTimeMillis() - startTime; - assertThat(runTime).isGreaterThanOrEqualTo(10L); - assertThat(runTime).isLessThan(10000L); - }); + try (ByteChannel channel = this.connection.open(10)) { + long startTime = System.currentTimeMillis(); + assertThatExceptionOfType(SocketTimeoutException.class) + .isThrownBy(() -> channel.read(ByteBuffer.allocate(5))).satisfies((ex) -> { + long runTime = System.currentTimeMillis() - startTime; + assertThat(runTime).isGreaterThanOrEqualTo(10L); + assertThat(runTime).isLessThan(10000L); + }); + } } static class MockServer { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuildpackCoordinatesTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuildpackCoordinatesTests.java index 568ee4f1e57..6c6941a9724 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuildpackCoordinatesTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuildpackCoordinatesTests.java @@ -57,35 +57,43 @@ class BuildpackCoordinatesTests extends AbstractJsonTests { } @Test - void fromTomlWhenMissingIDThrowsException() { - InputStream coordinates = createTomlStream(null, null, true, false); - assertThatIllegalArgumentException().isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) - .withMessageContaining("Buildpack descriptor must contain ID") - .withMessageContaining(this.archive.toString()); + void fromTomlWhenMissingIDThrowsException() throws IOException { + try (InputStream coordinates = createTomlStream(null, null, true, false)) { + assertThatIllegalArgumentException() + .isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) + .withMessageContaining("Buildpack descriptor must contain ID") + .withMessageContaining(this.archive.toString()); + } } @Test - void fromTomlWhenMissingVersionThrowsException() { - InputStream coordinates = createTomlStream("example/buildpack1", null, true, false); - assertThatIllegalArgumentException().isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) - .withMessageContaining("Buildpack descriptor must contain version") - .withMessageContaining(this.archive.toString()); + void fromTomlWhenMissingVersionThrowsException() throws IOException { + try (InputStream coordinates = createTomlStream("example/buildpack1", null, true, false)) { + assertThatIllegalArgumentException() + .isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) + .withMessageContaining("Buildpack descriptor must contain version") + .withMessageContaining(this.archive.toString()); + } } @Test - void fromTomlWhenMissingStacksAndOrderThrowsException() { - InputStream coordinates = createTomlStream("example/buildpack1", "0.0.1", false, false); - assertThatIllegalArgumentException().isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) - .withMessageContaining("Buildpack descriptor must contain either 'stacks' or 'order'") - .withMessageContaining(this.archive.toString()); + void fromTomlWhenMissingStacksAndOrderThrowsException() throws IOException { + try (InputStream coordinates = createTomlStream("example/buildpack1", "0.0.1", false, false)) { + assertThatIllegalArgumentException() + .isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) + .withMessageContaining("Buildpack descriptor must contain either 'stacks' or 'order'") + .withMessageContaining(this.archive.toString()); + } } @Test - void fromTomlWhenContainsBothStacksAndOrderThrowsException() { - InputStream coordinates = createTomlStream("example/buildpack1", "0.0.1", true, true); - assertThatIllegalArgumentException().isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) - .withMessageContaining("Buildpack descriptor must not contain both 'stacks' and 'order'") - .withMessageContaining(this.archive.toString()); + void fromTomlWhenContainsBothStacksAndOrderThrowsException() throws IOException { + try (InputStream coordinates = createTomlStream("example/buildpack1", "0.0.1", true, true)) { + assertThatIllegalArgumentException() + .isThrownBy(() -> BuildpackCoordinates.fromToml(coordinates, this.archive)) + .withMessageContaining("Buildpack descriptor must not contain both 'stacks' and 'order'") + .withMessageContaining(this.archive.toString()); + } } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java index 8f39cb4148e..8108bc329cc 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java @@ -585,8 +585,12 @@ abstract class AbstractBootArchiveIntegrationTests { for (String layerName : layerNames) { File layer = new File(root, layerName); assertThat(layer).isDirectory(); - extractedLayers.put(layerName, Files.walk(layer.toPath()).filter((path) -> path.toFile().isFile()) - .map(layer.toPath()::relativize).map(Path::toString).map(StringUtils::cleanPath).toList()); + List files; + try (Stream pathStream = Files.walk(layer.toPath())) { + files = pathStream.filter((path) -> path.toFile().isFile()).map(layer.toPath()::relativize) + .map(Path::toString).map(StringUtils::cleanPath).toList(); + } + extractedLayers.put(layerName, files); } return extractedLayers; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java index a3da6dfd078..90d2c9df5d9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java @@ -294,9 +294,10 @@ class JarFileTests { void getEntryUrlStream() throws Exception { URL url = new URL(this.jarFile.getUrl(), "1.dat"); url.openConnection(); - InputStream stream = url.openStream(); - assertThat(stream.read()).isEqualTo(1); - assertThat(stream.read()).isEqualTo(-1); + try (InputStream stream = url.openStream()) { + assertThat(stream.read()).isEqualTo(1); + assertThat(stream.read()).isEqualTo(-1); + } } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java index fa8c356b6a5..090588fd3bb 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.TestTemplate; @@ -173,10 +174,10 @@ public class AotTests { }); } - Stream collectRelativePaths(Path sourceDirectory) { - try { - return Files.walk(sourceDirectory).filter(Files::isRegularFile) - .map((path) -> path.subpath(sourceDirectory.getNameCount(), path.getNameCount())); + List collectRelativePaths(Path sourceDirectory) { + try (Stream pathStream = Files.walk(sourceDirectory)) { + return pathStream.filter(Files::isRegularFile) + .map((path) -> path.subpath(sourceDirectory.getNameCount(), path.getNameCount())).toList(); } catch (IOException ex) { throw new IllegalStateException(ex); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuildExtension.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuildExtension.java index 2e2bde0e8f7..07ace67c23b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuildExtension.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuildExtension.java @@ -47,6 +47,8 @@ class MavenBuildExtension implements TestTemplateInvocationContextProvider { @Override public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { try { + // Returning a stream which must be closed here is fine, as JUnit will take + // care of closing it return Files.list(Paths.get("build/maven-binaries")).map(MavenVersionTestTemplateInvocationContext::new); } catch (IOException ex) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java index 70696629dea..a128b8c978f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.stream.Stream; import javax.tools.Diagnostic; import javax.tools.DiagnosticListener; @@ -124,7 +125,10 @@ public abstract class AbstractAotMojo extends AbstractDependencyFilterMojo { protected final void compileSourceFiles(URL[] classPath, File sourcesDirectory, File outputDirectory) throws Exception { - List sourceFiles = Files.walk(sourcesDirectory.toPath()).filter(Files::isRegularFile).toList(); + List sourceFiles; + try (Stream pathStream = Files.walk(sourcesDirectory.toPath())) { + sourceFiles = pathStream.filter(Files::isRegularFile).toList(); + } if (sourceFiles.isEmpty()) { return; } @@ -167,8 +171,13 @@ public abstract class AbstractAotMojo extends AbstractDependencyFilterMojo { } protected final void copyAll(Path from, Path to) throws IOException { - List files = (Files.exists(from)) ? Files.walk(from).filter(Files::isRegularFile).toList() - : Collections.emptyList(); + if (!Files.exists(from)) { + return; + } + List files; + try (Stream pathStream = Files.walk(from)) { + files = pathStream.filter(Files::isRegularFile).toList(); + } for (Path file : files) { String relativeFileName = file.subpath(from.getNameCount(), file.getNameCount()).toString(); getLog().debug("Copying '" + relativeFileName + "' to " + to); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/ConfigTreePropertySource.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/ConfigTreePropertySource.java index 1a263ae7835..24bb5d5949b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/ConfigTreePropertySource.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/ConfigTreePropertySource.java @@ -30,6 +30,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.stream.Stream; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.boot.origin.Origin; @@ -204,16 +205,18 @@ public class ConfigTreePropertySource extends EnumerablePropertySource imp static Map findAll(Path sourceDirectory, Set