I’m facing an intermittent issue in a Java Spring application where byte arrays fetched asynchronously seem to lose data when written to files, despite logging correct byte lengths immediately after fetching. This problem does not occur when I run the operations synchronously.
@Service
public class DemoService {
@Autowired
private ProcessService fileProcessingService;
// Asynchronously fetches a byte array and writes it to a file
public CompletableFuture<Void> processAndWriteFile(String id, String tag, String filename) {
return getAttachmentFileById(id, tag)
.thenCompose(zipBytes -> {
if (zipBytes != null) {
return writeToFile(zipBytes, filename);
} else {
CompletableFuture<Void> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(new RuntimeException("Failed to retrieve bytes for ID: " + id));
return failedFuture;
}
});
}
private CompletableFuture<File> writeToFile(byte[] zipBytes, String filename) {
String tempDir = System.getProperty("java.io.tmpdir");
File tempFile = new File(tempDir, filename);
return CompletableFuture.supplyAsync(() -> {
try (FileOutputStream out = new FileOutputStream(tempFile)) {
out.write(zipBytes);
return tempFile;
} catch (IOException e) {
logger.error("Failed to write zip file to disk", e);
throw new RuntimeException("Failed to write zip file to disk", e);
}
});
}
}
The byte array fetched by getAttachmentFileById consistently logs the correct size.
After passing the byte array to writeToFile, the file occasionally ends up shorter than the logged size.
Question:
Could this issue be related to how CompletableFuture manages threads or handles byte arrays? How can I ensure the entire byte array is written to the file consistently without data loss?
Additional Details: Occurs intermittently, more frequently under load.