RFR: JDK-8319626: Override toString() for ZipFile [v7]
Jaikiran Pai
jpai at openjdk.org
Fri Dec 8 10:21:17 UTC 2023
On Fri, 1 Dec 2023 21:32:57 GMT, Justin Lu <jlu at openjdk.org> wrote:
>> Please review this PR and [CSR](https://bugs.openjdk.org/browse/JDK-8319982) which overrides and provides an implementation of `toString()` in _java.util.zip.ZipFile_ (and by extension, _java.util.jar.JarFile_).
>
> Justin Lu has updated the pull request incrementally with one additional commit since the last revision:
>
> drop additional specification
src/java.base/share/classes/java/util/zip/ZipFile.java line 494:
> 492: @Override
> 493: public String toString() {
> 494: return res.zsrc.key.file.getName()
Hello Justin, relying on `res.zsrc.key.file` to get to the file name can cause troubles. For example, consider this usage (which I ran in jshell) with this proposed change in this PR:
jshell> import java.util.zip.*
jshell> ZipFile zf = new ZipFile("/tmp/workdir.zip")
zf ==> workdir.zip at 34c45dca
jshell> zf.close()
jshell> zf.toString()
| Exception java.lang.NullPointerException: Cannot read field "key" because "this.res.zsrc" is null
| at ZipFile.toString (ZipFile.java:494)
| at (#4:1)
What I do here is that I call `ZipFile.toString()` after I (intentionally) close the `ZipFile`. The `toString()` call leads to `NullPointerException` because on closing the `ZipFile` instance we clean up the resource it holds on to.
I think what we can do here is, something like (the following diff was generated on top of the current state of this PR):
diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java
index 67a5e65089f..2b6996294e1 100644
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -95,7 +95,8 @@
*/
public class ZipFile implements ZipConstants, Closeable {
- private final String name; // zip file name
+ private final String filePath; // zip file path
+ private final String fileName; // name of the file
private volatile boolean closeRequested;
// The "resource" used by this zip file that needs to be
@@ -245,7 +246,8 @@ public ZipFile(File file, int mode, Charset charset) throws IOException
}
Objects.requireNonNull(charset, "charset");
- this.name = name;
+ this.filePath = name;
+ this.fileName = file.getName();
long t0 = System.nanoTime();
this.res = new CleanableResource(this, ZipCoder.get(charset), file, mode);
@@ -483,7 +485,7 @@ public int available() throws IOException {
* @return the path name of the ZIP file
*/
public String getName() {
- return name;
+ return filePath;
}
/**
@@ -491,7 +493,7 @@ public String getName() {
*/
@Override
public String toString() {
- return res.zsrc.key.file.getName()
+ return this.fileName
+ "@" + Integer.toHexString(System.identityHashCode(this));
}
The above example usage now works even after I close the ZipFile. I haven't run other tests, but given that this doesn't change any APIs or their implementation, I think the tests would run fine too.
Do you see any issues with this?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/16643#discussion_r1420232060
More information about the core-libs-dev
mailing list