RFR: 8350880: (zipfs) Add support for read-only zip file systems
David Beaumont
duke at openjdk.org
Mon May 12 10:05:59 UTC 2025
On Mon, 12 May 2025 09:40:56 GMT, David Beaumont <duke at openjdk.org> wrote:
> Adding read-only support to ZipFileSystem.
>
> The new `accessMode` environment property allows for readOnly and readWrite values, and ensures that the requested mode is consistent with what's returned.
>
> This involved a little refactoring to ensure that "read only" state was set initially and only unset at the end of initialization if appropriate.
>
> By making 2 methods return values (rather than silently set non-final fields as a side effect) it's now clear in what order fields are initialized and which are final (sadly there are still non-final fields, but only a split of this class into two types can fix that, since determining multi-jar support requires reading the file system).
Preloading some explanatory comment.
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 83:
> 81: private static final boolean isWindows = System.getProperty("os.name")
> 82: .startsWith("Windows");
> 83: private static final byte[] ROOTPATH = new byte[]{'/'};
Whitespace format changes from my editor - will revert (sorry hadn't spotted).
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 89:
> 87:
> 88: // Posix file permissions allow per-file access control in a posix-like fashion.
> 89: // Note that using a "readOnly" access mode will force all files, and the
Not correct now - will fix.
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 198:
> 196: this.defaultOwner = supportPosix ? initOwner(zfpath, env) : null;
> 197: this.defaultGroup = supportPosix ? initGroup(zfpath, env) : null;
> 198: this.defaultPermissions = supportPosix ? Collections.unmodifiableSet(initPermissions(env)) : null;
Ensuring this is unmodifiable to avoid risk of returning a modifiable enum set.
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 221:
> 219: }
> 220: // sm and existence check
> 221: zfpath.getFileSystem().provider().checkAccess(zfpath, java.nio.file.AccessMode.READ);
Type name clash with existing AccessMode class. Since new enum is private, happy to rename.
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 241:
> 239: // is why they are the only non-final fields), and it requires that the
> 240: // inode map has been initialized.
> 241: Optional<Integer> multiReleaseVersion = determineReleaseVersion(env);
Now release version and entry lookup determination always happen on a read-only file system.
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 259:
> 257:
> 258: // Pass "this" as a parameter after everything else is set up.
> 259: this.rootdir = new ZipPath(this, new byte[]{'/'});
This could probably be set above release version etc. but it's a choice of either:
1. waiting until everything is set up before passing "this"
2. letting an incomplete "this" instance get passed to another class (possible escape risk?)
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 264:
> 262: /**
> 263: * Return the compression method to use (STORED or DEFLATED). If the
> 264: * property {@code compressionMethod} is set use its value to determine
Typo fix (too many m's).
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 377:
> 375: Object o = env.get(PROPERTY_DEFAULT_PERMISSIONS);
> 376: if (o == null) {
> 377: return PosixFilePermissions.fromString("rwxrwxrwx");
Since DEFAULT_PERMISSIONS was mutable and only used exactly once, it seems better to just inline it where it's clear what it actually is based off. Better readability.
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java line 1458:
> 1456: * use its value to determine the requested version. If not use the value of the "multi-release" property.
> 1457: */
> 1458: private Optional<Integer> determineReleaseVersion(Map<String, ?> env) throws IOException {
Refactored to return the value rather than side-effect instance fields.
test/jdk/jdk/nio/zipfs/NewFileSystemTests.java line 180:
> 178: */
> 179: @Test
> 180: public void testNoSuchFileFailure() {
In theory some of these could be split more, but they are uncomplicated sanity checks.
test/jdk/jdk/nio/zipfs/Utils.java line 52:
> 50: */
> 51: static Path createJarFile(String name, String... entries) throws IOException {
> 52: Path jarFile = Paths.get(name);
Previous tests always had the test file called the same thing.
Note that in jtreg tests, the file of the same name often already exists in the test directory.
I tried adding a "ensure file doesn't already exist" check and it fails lots of tests.
-------------
PR Review: https://git.openjdk.org/jdk/pull/25178#pullrequestreview-2832583353
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084284309
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084288335
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084292488
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084296094
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084297859
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084301697
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084302415
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084306071
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084307536
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084311454
PR Review Comment: https://git.openjdk.org/jdk/pull/25178#discussion_r2084317768
More information about the nio-dev
mailing list