-
Notifications
You must be signed in to change notification settings - Fork 391
Description
Version
2.15.0
Bug description
I'm seeing an issue where using SftpFileSystemProvider to download a file does not release resources, even when reading the file within a try(...) block. However, this only reproduces when I'm running from an executable jar.
Minimal-ish example:
public static void main(String[] args) throws Exception {
var uri = args.length == 1 ? URI.create(args[0]) : URI.create(
// use: docker run -p 2200:22 -v path-to-file:/home/demo/sftp --rm -it emberstack/sftp
"sftp://localhost:2200/sftp/anyfile.txt"
);
for (int i = 0; i < 100; i++) {
var data = fetchData(uri, "demo", "demo");
System.out.println(Thread.getAllStackTraces().size() + " threads");
}
}
public static byte[] fetchData(URI url, String user, String pw) throws Exception {
URI uri = SftpFileSystemProvider.createFileSystemURI(url.getHost(), url.getPort(), user, pw);
try (FileSystem fs = FileSystems.newFileSystem(uri, Map.of(), Thread.currentThread()
.getContextClassLoader())) {
Path remotePath = fs.getPath(url.getPath());
return Files.readAllBytes(remotePath);
}
}Actual behavior
When I package the app into a jar with the spring boot plugin, which uses a custom classloader, the number of threads increases by 14 with each fetchData call.
./gradlew bootJar && java -jar build/libs/sshd-leak-0.0.1-SNAPSHOT.jar
21 threads
35 threads
49 threads
63 threads
77 threads
91 threads
105 threads
119 threads
133 threads
147 threads
161 threads
175 threads
189 threads
203 threads
217 threads
231 threads
etc. The DirectMemory usage also increases each time, and Spring's docker images annoyingly default DirectMemory to 10MB, so this causes docker images to run out of memory quickly. I've also reproduced this behavior from scala-cli's jar assembly jars, so it isn't completely unique to Spring.
Expected behavior
With spring-boot gradle plugin, when I run ./gradlew bootRun, or just from IntelliJ, everything works as expected:
20 threads
21 threads
22 threads
23 threads
24 threads
25 threads
26 threads
27 threads
28 threads
29 threads
30 threads
30 threads
30 threads
30 threads
30 threads
30 threads
30 threads
The threads grow but they stabilize.
Relevant log output
Other information
I can provide a full, working gradle project if that's helpful.