SDK Version
minio-java 9.0.3
Description
When stagingFilename is used, uploadSnowballObjects() opens the generated TAR file with RandomAccessFile inside a try-with-resources block:
try (RandomAccessFile file = new RandomAccessFile(args.stagingFilename(), "r")) {
return putObject(new PutObjectAPIArgs(args, file, length, headers));
}
However, putObject() returns a CompletableFuture, and the HTTP request is executed asynchronously.
This means the RandomAccessFile may be closed immediately after putObject() returns, while the HTTP request is still reading from it.
Potential sequence:
open `RandomAccessFile`
↓
`putObject()` enqueues async HTTP request
↓
` putObject()` returns `CompletableFuture`
↓
try-with-resources closes `RandomAccessFile`
↓
HTTP request tries to read from the closed file
Reproduction
MinioClient client =
MinioClient.builder()
.credentials("minio", "Minio@123")
.endpoint("http://192.168.1.10:9000")
.build();
client
.uploadSnowballObjects(
UploadSnowballObjectsArgs
.builder()
.bucket("migration")
.objects(
List.of(
new SnowballObject("test/test.docx", "/tmp/output.docx")
)
)
.stagingFilename("/tmp/test.tar")
.build()
);
Result
The upload may fail while OkHttp is reading the request body because the underlying RandomAccessFile has already been closed.
For example, an exception similar to the following may occur:
Exception in thread "main" io.minio.errors.MinioException: java.io.IOException: Stream Closed
at io.minio.Http$RequestBody.<init>(Http.java:1046)
at io.minio.Http$Body.toRequestBody(Http.java:994)
at io.minio.Http$S3Request.toRequest(Http.java:1798)
at io.minio.Http$S3Request.toRequest(Http.java:1859)
at io.minio.BaseS3Client.executeAsync(BaseS3Client.java:345)
at io.minio.BaseS3Client.lambda$executeAsync$1(BaseS3Client.java:519)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1150)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
at io.minio.BaseS3Client$1.onResponse(BaseS3Client.java:381)
at io.minio.BaseS3Client$1.onResponse(BaseS3Client.java:367)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:842)
Caused by: java.io.IOException: Stream Closed
at java.base/java.io.RandomAccessFile.getFilePointer(Native Method)
at io.minio.Http$RequestBody.<init>(Http.java:1044)
Expected Behavior
The RandomAccessFile should remain open until the asynchronous upload completes.
Could you please confirm whether this is a resource lifecycle issue in MinioAsyncClient#uploadSnowballObjects()?
SDK Version
minio-java 9.0.3
Description
When
stagingFilenameis used,uploadSnowballObjects()opens the generated TAR file with RandomAccessFile inside a try-with-resources block:However,
putObject()returns aCompletableFuture, and the HTTP request is executed asynchronously.This means the RandomAccessFile may be closed immediately after
putObject()returns, while the HTTP request is still reading from it.Potential sequence:
Reproduction
Result
The upload may fail while OkHttp is reading the request body because the underlying RandomAccessFile has already been closed.
For example, an exception similar to the following may occur:
Expected Behavior
The
RandomAccessFileshould remain open until the asynchronous upload completes.Could you please confirm whether this is a resource lifecycle issue in
MinioAsyncClient#uploadSnowballObjects()?