JDK-8225763 : Inflater and Deflater should implement AutoCloseable
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-06-14
  • Updated: 2025-01-27
  • Resolved: 2025-01-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 25
25 b06Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8347816 :  
Description
The Inflater and Deflater classes require the caller to call end() after use, because these objects retain references to native memory. This is clearly documented. However, there is no way to use these classes with the try-with-resources statement, because they don't implement AutoCloseable.

These classes should implement a close() method that simply calls end(), and the classes should be retrofitted to implement AutoCloseable.

Comments
Changeset: 36b7abd6 Branch: master Author: Jaikiran Pai <jpai@openjdk.org> Date: 2025-01-15 01:04:44 +0000 URL: https://git.openjdk.org/jdk/commit/36b7abd617addcf6c7af37788abed7a714b175a5
15-01-2025

Not a review per se, just wanted to note for the record that the changes proposed here would make resource management when using a custom Deflater/Inflater constructor in the Deflater/Inflater Input/OutputStreams a lot more elegant. Specifically, example snippets could be added showing how to close both the Deflater and the stream in the same try-with-resources: try (var deflater = new Deflater(); var os = new DeflaterOutputStream(out, deflater, 1024)) { os.write(content); } {code} Food for thought for JDK-8066583
26-11-2024

[copying my PR comments from 2024-06-16 here so that they don't get lost] Hi Jai, thanks for picking this up. Several points of discussion here. Nothing fatal, but as I said in 2019 :-) just a few wrinkles to iron out. I looked mainly at Deflater, but I think the issues also all apply to Inflater too. # class specification I think the class specification needs to be clearer about the positioning of and the relationship between end() and close(). The end() method has done the real work of "closing" since the classes were introduced. We're retrofitting them to to have a close() method that's essentially just a synonym for end(), and it's still perfectly legal for clients and subclasses to call end() instead of close(). I think we need to say that close() is present mainly to support AutoCloseable and try-with-resources. # end() specification I don't think that "may throw an exception" is strong enough. Also, on these classes (not subclasses) end() is idemopotent, isn't it? If so, this should be specified. The end() specs need to say something like, closes and releases resources, etc., henceforth operations will throw an exception (which? -- see below) but that subsequent calls to end() do nothing. # Which exceptions on closed Deflater/Inflater? Oddly, it doesn't seem to be specified anywhere what exceptions are thrown if operations are attempted on a closed object. And the implementation actually throws NPE??!? Ideally we should specify what exception is thrown in this circumstance, but NPE seems wrong. Maybe we want to change the behavior to throw a different exception type. IllegalStateException seems like a reasonable candidate. # close() specification The 2019 discussion kind of assumed that we want close() to be idempotent. I'm not sure this is necessary. Alan said the implementation might need to be "heroic" but Peter Levart's arrangement (carried through here, apparently) isn't terribly bad. And [~liach] suggests adding more comments on this code, quite reasonably... but the comment begs the question, why do we need to avoid calling end() more than once? I'm rethinking the need for close() to be idempotent. Maybe close() should simply call end(). It would simplify the implementation and the specs -- the implSpec would simply say that it calls the end() method. This would only be a problem if a) some arrangement of TWR ends up calling close() twice, which apparently it doesn't; b) there is a subclass; and c) the subclass's end() method is not idempotent. As far as I can tell we haven't found any example of any of these. It thus seems to me that having extra logic in close() to avoid calling end() more than once is solving a non-problem. It also fits more closely to the model of "close() is simply a synonym for end()".
05-11-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/19675 Date: 2024-06-12 10:45:30 +0000
09-07-2024

Review threads on core-libs-dev: http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-June/061079.html http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-July/061177.html http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-July/061229.html
23-07-2019