Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8031077

(zipfs) ZipFileSystemProvider.getFileSystem does not create zip file automatically

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Cannot Reproduce
    • Affects Version/s: 7, 8
    • Fix Version/s: tbd
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Introduced In Version:
      7

      Description

      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.

        Attachments

          Activity

            People

            • Assignee:
              sherman Xueming Shen
              Reporter:
              sherman Xueming Shen
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: