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

Philippe Marschall philippe.marschall at
Wed Dec 25 07:23:32 PST 2013


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


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

  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");
      } finally {
    } finally {

I tested with the latest b121 of JDK8.


More information about the nio-dev mailing list