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

ZipFileSystemProvider do not correctly clear its internal map on close

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      If the source zip file has been deleted, ZipFileSystem.close() fails and the internal map jdk.nio.zipfs.ZipFileSystemProvider.filesystems is not properly cleared.

      Even if the source file is recreated, it is not possible to use ZipFileSystem later on this path.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a jar file on the file system
      2. Open a FileSystems.newFileSystem(new URI("jar:..."))
      3. Delete the source file in the file system
      4. Close the jar FileSystem
      5. Recreate the source file in the file system
      6. Open a new FileSystems.newFileSystem(new URI("jar:..."))

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      At step 4, FileSystem.close() should not throw an exception
      At step 6, we should be able to create new jar FileSystem without exception
      ACTUAL -
      - step 4, FileSystem.close() fails with a NoSuchFileException
      - step 6 throws a FileSystemAlreadyExistsException, this path is never usable.

      ---------- BEGIN SOURCE ----------
      import java.io.OutputStream;
      import java.net.URI;
      import java.nio.file.*;
      import java.util.Collections;
      import java.util.zip.ZipOutputStream;

      public class BugZipFileSystem {

      public static void main(String[] args) {
      try {
      System.out.println("Java version: "+System.getProperty("java.runtime.version"));
      //1. Create a zip file
      Path zipFile = Files.createTempFile("buZipFilSystem", ".zip");
      try (OutputStream out = Files.newOutputStream(zipFile)) {
      new ZipOutputStream(out).close();
      }
      URI zipUri = new URI("jar:" + zipFile.toUri());

      //2. Instantiate a ZipFileSystem
      FileSystem zipFs = FileSystems.newFileSystem(zipUri, Collections.EMPTY_MAP);

      //3. Delete the source file
      Files.delete(zipFile);

      //4. Close the ZipFileSystem
      try {
      zipFs.close();
      } catch (NoSuchFileException e) {
      System.out.println("zipFs.close() throw NoSuchFileException: not sure it was a good thing!");
      System.out.println("The internal Map jdk.nio.zipfs.ZipFileSystemProvider.filesystems is not correctly cleared");
      }

      //5. Recreate the zip
      try (OutputStream out = Files.newOutputStream(zipFile)) {
      new ZipOutputStream(out).close();
      }

      //6. It is now impossible to re-use the zipFs or instantiate a new one
      zipFs = FileSystems.getFileSystem(zipUri);
      if (!zipFs.isOpen()) System.out.println("zipFs is always internally referenced but closed and not usable");
      try {
      zipFs = FileSystems.newFileSystem(zipUri, Collections.EMPTY_MAP);
      } catch (Exception e) {
      System.out.println("A new ZipFs can not be instanciated because it is referenced in the internal map jdk.nio.zipfs.ZipFileSystemProvider.filesystems: " + e);
      }

      } catch (Exception e) {
      e.printStackTrace();
      }

      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Before calling ZipFileSystem.close() check if the file has been deleted and recreate it temporarily (along with its parent folders)

      FREQUENCY : always


            jpai Jaikiran Pai
            webbuggrp Webbug Group
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: