Path -> URI -> Path round trip fails for lazily created zip file systems

Xueming Shen xueming.shen at oracle.com
Fri Dec 27 11:20:43 PST 2013


Hi Philippe,

I've file a new issue into the bug system.
https://bugs.openjdk.java.net/browse/JDK-8031077

The "realPath" need to be check and set, if null (in case of "create 
new"), before to be added
into the map "filesystems". The check is to obtain the real path to 
check whether or not the
filesystem (may represented by different url) has been open already, 
throw FSAEE if yet, as
the API spec requests.

-Sherman

On 12/25/13 7:23 AM, Philippe Marschall wrote:
> When you create a ZIP file system on a zip file that doesn’t exist
> (option ”create" set to "false”) then the following will fail
>
> Paths.get(path.toUri())
>
> This issue is that in this case the file system is stored under a null
> key in ZipFileSystemProvider#filesystems instead of the real path
> (this may break other things as well). It seems to be caused by the
> following code in ZipFileSystemProvider.newFileSystem(URI, Map<String,
> ?>)
>
>      public FileSystem newFileSystem(URI uri, Map<String, ?> env)
>          throws IOException
>      {
>          Path path = uriToPath(uri);
>          synchronized(filesystems) {
>              Path realPath = null;
>              if (ensureFile(path)) {
>                  realPath = path.toRealPath();
>                  if (filesystems.containsKey(realPath))
>                      throw new FileSystemAlreadyExistsException();
>              }
>              ZipFileSystem zipfs = null;
>              try {
>                  zipfs = new ZipFileSystem(this, path, env);
>              } catch (ZipError ze) {
>                  String pname = path.toString();
>                  if (pname.endsWith(".zip") || pname.endsWith(".jar"))
>                      throw ze;
>                  // assume NOT a zip/jar file
>                  throw new UnsupportedOperationException();
>              }
>              filesystems.put(realPath, zipfs);
>              return zipfs;
>          }
>      }
>
> The problem is that when “path” does not exist then #ensureFile will
> return false. In this case realPath will remain null. I don’t know why
> this check is done there so I’m not sure what the fix is.
>
> A simple test case for this is
>
>
>    @Test
>    public void jarToUriRegression() throws IOException {
>      Path jarFolder = Files.createTempDirectory("jartest");
>      try {
>        Path jarFile = jarFolder.resolve("test.jar");
>        try {
>          Map<String, String> env = Collections.singletonMap("create", "true");
>          URI uri = URI.create("jar:" + jarFile.toUri());
>          try (FileSystem jarfs = FileSystems.newFileSystem(uri, env)) {
>            Path p = jarfs.getPath("hello.txt");
>            assertNotNull(Paths.get(p.toUri()));
>          }
>        } finally {
>          Files.delete(jarFile);
>        }
>      } finally {
>        Files.delete(jarFolder);
>      }
>    }
>
> I tested with the latest b121 of JDK8.



More information about the nio-dev mailing list