Nested ZipFileSystems cause issues with URI parsing
Mitchell Skaggs
skaggsm333 at gmail.com
Tue Jun 9 09:24:40 UTC 2020
Lance,
I finally got a dev environment set up and I've been working on tests (it
takes *forever* for Mercurial to update and for the project to build, so
I've had a lot of time to slack off <https://xkcd.com/303/>).
However, I've run into an issue with the two methods
FileSystemProvider#newFileSystem(Path,Map) and
FileSystemProvider#newFileSystem(URI,Map). It's only mentioned in passing,
but from FileSystemProvider#getFileSystem(URI)'s docs: "File systems
created (sic) the newFileSystem(Path,Map) method are not returned by this
method." This causes issues for ZipFileSystemProvider as the only way to
acquire a "raw" ZipFileSystem to work with is through the method taking a
Path. I tried adding new FileSystems created through the Path param
overload to the provider's map, but that causes test failures in
ZipFSTester#test1(FileSystem). Should I try to slightly alter the behavior
of FileSystemProvider#newFileSystem(Path,Map), or should I just use a hacky
workaround in my test?
This is my current patch including tests:
Index: test/jdk/jdk/nio/zipfs/NestedZipFSTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/jdk/jdk/nio/zipfs/NestedZipFSTests.java (revision
59637+:9610e9b776ca+)
+++ test/jdk/jdk/nio/zipfs/NestedZipFSTests.java (revision
59637+:9610e9b776ca+)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.*;
+import java.util.Map;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @summary Validate that a multi-level (nested) jar files can be opened
by URI
+ * @modules jdk.zipfs
+ * @run testng/othervm NestedZipFSTests
+ */
+public class NestedZipFSTests {
+
+ /**
+ * Validate that a 2-level jar file can be opened by URI
+ */
+ @Test
+ public void testOpens2LevelJar() throws Exception {
+ Path jar1Path = Path.of("jar1.jar");
+
+ try (FileSystem jar1 = FileSystems.newFileSystem(new URI("jar",
jar1Path.toUri() + "!/", null), Map.of("create", true))) {
+ Path jar2Path = jar1.getPath("jar2.jar");
+ try (FileSystem jar2 = FileSystems.newFileSystem(new
URI("jar", jar2Path.toUri() + "!/", null), Map.of("create", true))) {
+ Path nestedFilePath = jar2.getPath("test.txt");
+ Path newPath = Path.of(nestedFilePath.toUri());
+
+ assertEquals(nestedFilePath, newPath);
+ }
+ }
+ }
+
+ /**
+ * Validate that a 3-level jar file can be opened by URI
+ */
+ @Test
+ public void testOpens3LevelJar() throws Exception {
+ Path jar1Path = Path.of("jar1.jar");
+
+ try (FileSystem jar1 = FileSystems.newFileSystem(new URI("jar",
jar1Path.toUri() + "!/", null), Map.of("create", true))) {
+ Path jar2Path = jar1.getPath("jar2.jar");
+ try (FileSystem jar2 = FileSystems.newFileSystem(new
URI("jar", jar2Path.toUri() + "!/", null), Map.of("create", true))) {
+ Path jar3Path = jar2.getPath("jar3.jar");
+ try (FileSystem jar3 = FileSystems.newFileSystem(new
URI("jar", jar3Path.toUri() + "!/", null), Map.of("create", true))) {
+ Path nestedFilePath = jar3.getPath("test.txt");
+ Path newPath = Path.of(nestedFilePath.toUri());
+
+ assertEquals(nestedFilePath, newPath);
+ }
+ }
+ }
+ }
+}
Index: src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java
(revision 59637:9610e9b776cae5cbcdcce2e48dcf471ef7a8da1c)
+++ src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java
(revision 59637+:9610e9b776ca+)
@@ -69,11 +69,11 @@
try {
// only support legacy JAR URL syntax jar:{uri}!/{entry} for
now
String spec = uri.getRawSchemeSpecificPart();
- int sep = spec.indexOf("!/");
+ int sep = spec.lastIndexOf("!/");
if (sep != -1) {
spec = spec.substring(0, sep);
}
- return Paths.get(new URI(spec)).toAbsolutePath();
+ return Path.of(new URI(spec)).toAbsolutePath();
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
@@ -134,7 +134,7 @@
@Override
public Path getPath(URI uri) {
String spec = uri.getSchemeSpecificPart();
- int sep = spec.indexOf("!/");
+ int sep = spec.lastIndexOf("!/");
if (sep == -1)
throw new IllegalArgumentException("URI: "
+ uri
The "hacky workaround" I mentioned is the manual construction of Jar URIs
in the tests. I feel it could be improved and made easier to use, but it
compiles and the tests pass.
Thanks,
Mitchell
On Sun, Jun 7, 2020 at 3:40 AM Alan Bateman <Alan.Bateman at oracle.com> wrote:
> On 06/06/2020 20:12, Mitchell Skaggs wrote:
> > :
> >
> > I have a test, but I'm not sure where to put it and how to build
> > everything on Windows. Here's a "vanilla" version of the test that
> > demonstrates the issue:
> >
> I see Lance is providing advice on how to create a test (thanks Lance).
> I could imagine expanding the test coverage quite a bit to to cover the
> various scenarios that arise with N levels of nesting, particularly in
> cases where an enclosing file system is closed (and unregistered) and
> the behavior of subsequent calls to Path.of(URI). Thanks for working on
> this.
>
> -Alan
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/nio-dev/attachments/20200609/6b3fd6da/attachment-0001.htm>
More information about the nio-dev
mailing list