JDK-8002390 : (zipfs) Problems moving files between zip file systems
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 7,7u9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2012-11-07
  • Updated: 2013-07-31
  • Resolved: 2013-04-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
7u40Fixed 8 b87Fixed
While working with the new ZipFileSystem to modify the contents of a zip file, encountered some issues.

The issue occurs when a file within a zip file is moved to a different location within the same zip and a FileVisitor is invoked by Files.walkFileTree the original (no longer existing file) will attempted to be visited by ZipFileSystemProvider and throw a NoSuchFileException.

Attached is a standalone java file that can reproduce the issue.

Tested this on Java 7 u9 and the issue still exists.

The code creates a zip file with 5 elements in a sub directory, writes the content to disk, prints the contents of the zip file using Files.walkFileTree, moves one file from a subfolder to the root folder, then prints the contents of the zip file using Files.walkFileTree again.

a fix and test has been posted for this issue. I'll need to co-ordinate with Sherman to have it pushed. http://cr.openjdk.java.net/~sherman/8002390/webrev/

two modifications can be made to solve this problem. these are to the update and updateDelete / removeFromTree. Both of these work fine without modification if the move update is performed on a ZFS which has not been closed, and synced to disk. When the filesystem has been closed and written to disk, and then "re-open" (i.e. newFileSystem is invoked on FileSystems) the reconstituted ZFS has a slightly different representation in memory. Thus update has to take into account that the update Entry object might be a COPY (not just NEW or FILECH) and the updateDelete/removeFromTree has to allow for the fact that the IndexNodes being compared may not refer to same object instance, but may refer to a copy returned from the CEN, as per the getEntry0 method, as such it requires to invoke equals rather than ==. The key question then is: "why is the IndexNode an instance of Entry when the ZFS is newly created and manipulated in memory without being written to disk, while this is not the case when the ZFS is closed, written to disk and the re-opened ?" We'd need to defer to the designer Xueming Shen, with respect to this.

The file system indexes are left in an inconsistent state after the move. This doesn't happen if the sample application is modified not to close and re-open (Files.newFileSystem) the file system OR if we flush (close and re-open) the file system, move and the flush the file system again. We can make a couple of changes to ZipFileSystem.update method to allieviate the problem. But these raise one or two deeper questions, which require further analysis of the file move flow.