From 3ac5fda632708ea03c58e91149dca9f1e7c54cd2 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 27 Nov 2015 19:25:30 +0100 Subject: [PATCH] more robust code for zip handles when the files were changed (IDEA-148458) --- .../intellij/openapi/vfs/impl/ZipHandler.java | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/impl/ZipHandler.java b/platform/core-impl/src/com/intellij/openapi/vfs/impl/ZipHandler.java index 99e908cd6950..7b05e682dcb6 100644 --- a/platform/core-impl/src/com/intellij/openapi/vfs/impl/ZipHandler.java +++ b/platform/core-impl/src/com/intellij/openapi/vfs/impl/ZipHandler.java @@ -35,8 +35,8 @@ import java.util.zip.ZipFile; public class ZipHandler extends ArchiveHandler { private volatile String myCanonicalPathToZip = null; - private volatile long myFileStamp = DEFAULT_TIMESTAMP; - private volatile long myFileLength = DEFAULT_LENGTH; + private volatile long myFileStamp; + private volatile long myFileLength; public ZipHandler(@NotNull String path) { super(path); @@ -45,8 +45,12 @@ public class ZipHandler extends ArchiveHandler { private static final FileAccessorCache ourZipFileFileAccessorCache = new FileAccessorCache(20, 10) { @Override protected ZipFile createAccessor(ZipHandler key) throws IOException { - key.getFileStamp(); // cache file stamp and length - return new ZipFile(key.getCanonicalPathToZip()); + final String canonicalPathToZip = key.getCanonicalPathToZip(); + FileAttributes attributes = FileSystemUtil.getAttributes(canonicalPathToZip); + key.myFileStamp = attributes != null ? attributes.lastModified : DEFAULT_TIMESTAMP; + key.myFileLength = attributes != null ? attributes.length : DEFAULT_LENGTH; + + return new ZipFile(canonicalPathToZip); } @Override @@ -75,16 +79,6 @@ public class ZipHandler extends ArchiveHandler { return value; } - private long getFileStamp() { - long stamp = myFileStamp; - if (stamp == DEFAULT_TIMESTAMP) { - FileAttributes attributes = FileSystemUtil.getAttributes(getFileToUse()); - myFileStamp = stamp = attributes != null ? attributes.lastModified : DEFAULT_TIMESTAMP; - myFileLength = attributes != null ? attributes.length : DEFAULT_LENGTH; - } - return stamp; - } - @NotNull @Override protected Map createEntriesMap() throws IOException { @@ -114,17 +108,16 @@ public class ZipHandler extends ArchiveHandler { if (getFile() == getFileToUse()) { // files are canonicalized // IDEA-148458, http://bugs.java.com/view_bug.do?bug_id=4425695, JVM crashes on use of opened ZipFile after it was updated // Reopen file if the file has been changed - FileAttributes attributes = FileSystemUtil.getAttributes(getFileToUse()); + FileAttributes attributes = FileSystemUtil.getAttributes(getCanonicalPathToZip()); if (attributes == null) { throw new FileNotFoundException(getCanonicalPathToZip()); } - if (attributes.lastModified == getFileStamp() && attributes.length == myFileLength) return handle; + if (attributes.lastModified == myFileStamp && attributes.length == myFileLength) return handle; - handle.release(); + // Note that zip_util.c#ZIP_Get_From_Cache will allow us to have duplicated ZipFile instances without a problem removeZipHandlerFromCache(); - myFileStamp = DEFAULT_TIMESTAMP; - myFileLength = DEFAULT_LENGTH; + handle.release(); handle = ourZipFileFileAccessorCache.get(this); } @@ -163,7 +156,7 @@ public class ZipHandler extends ArchiveHandler { if (".".equals(path.second)) { return parentInfo; } - info = store(map, parentInfo, path.second, isDirectory, entry.getSize(), getFileStamp(), entryName); + info = store(map, parentInfo, path.second, isDirectory, entry.getSize(), myFileStamp, entryName); return info; }