Try-with-resources closes AutoCloseable resources when control leaves its block, including when the block throws.
Java try-with-resources: close order and suppressed failures
Bind cleanup to the acquisition scope
Files, streams, sockets, and database statements can hold resources that garbage collection does not release promptly enough. A lexical cleanup boundary states when the operation is finished with them.
Java 8 declares resources inside the try parentheses. If several are declared, they close in reverse declaration order. If acquiring a later resource fails, already acquired resources are still eligible for the cleanup performed by the statement.
The program uses a small diagnostic AutoCloseable to make both normal block failure and close failure observable. It does not need a real connection or file to explain the ordering rule.
Preserve the primary failure
When the body throws and close also throws, the body’s exception remains the primary one and the close failure becomes suppressed. getSuppressed exposes it for diagnostics. A close failure with no earlier body failure can instead become the thrown exception.
This distinction helps identify what first broke. A log that prints only the primary message can hide the cleanup failure. A log that reports only close can hide the actual failed operation.
Close is not a transaction rollback. Closing a database connection, writer, or custom resource does not imply that every preceding external effect was reversed. Define transaction and durability behavior separately.
Working program
public class ResourceFailureOrder {
static final class BatchLease implements AutoCloseable {
@Override
public void close() {
throw new IllegalStateException("lease close failed");
}
}
public static void main(String[] args) {
try (BatchLease lease = new BatchLease()) {
throw new IllegalArgumentException("batch validation failed");
} catch (Exception failure) {
System.out.println(failure.getMessage());
for (Throwable suppressed : failure.getSuppressed()) {
System.out.println("suppressed: " + suppressed.getMessage());
}
}
}
}Output
batch validation failed
suppressed: lease close failedCost and design choices
With r resources, cleanup invokes up to r close operations in reverse order. The actual time and memory costs belong to each resource implementation. Closing a network resource can block; O(r) method calls does not promise a small wall-clock duration.
The statement avoids repeatedly writing finally cleanup logic at each call site. It does not make opening a resource free or allow keeping unlimited resources alive in one scope.
For a custom AutoCloseable, document whether close is idempotent, whether it can fail, and whether the resource can be used afterward. Those behaviors cannot be inferred from the interface alone.
Connected lessons
Continue with Readers and files, Failure context, Explicit worker shutdown.
Common Mistakes
- Do not assume close failures are discarded.
- Do not treat close as an automatic rollback of external side effects.
- Do not rely on garbage collection for a prompt resource release deadline.
