6988106: javac report 'java.lang.IllegalMonitorStateException'
Reviewed-by: ksrini
--- a/langtools/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java Mon Jan 24 16:34:25 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java Mon Jan 24 16:38:56 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,10 @@
import java.io.File;
import java.io.IOException;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import com.sun.tools.javac.util.Context;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
/**
* Caching implementation of FSInfo.
--- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Mon Jan 24 16:34:25 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Mon Jan 24 16:38:56 2011 -0800
@@ -76,8 +76,6 @@
*/
public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager {
- boolean useZipFileIndex;
-
public static char[] toArray(CharBuffer buffer) {
if (buffer.hasArray())
return ((CharBuffer)buffer.compact().flip()).array();
@@ -91,6 +89,9 @@
private FSInfo fsInfo;
+ private boolean useZipFileIndex;
+ private ZipFileIndexCache zipFileIndexCache;
+
private final File uninited = new File("U N I N I T E D");
private final Set<JavaFileObject.Kind> sourceOrClass =
@@ -163,7 +164,11 @@
fsInfo = FSInfo.instance(context);
- useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null;
+ // retain check for system property for compatibility
+ useZipFileIndex = options.isUnset("useJavaUtilZip")
+ && System.getProperty("useJavaUtilZip") == null;
+ if (useZipFileIndex)
+ zipFileIndexCache = ZipFileIndexCache.getSharedInstance();
mmappedIO = options.isSet("mmappedIO");
ignoreSymbolFile = options.isSet("ignore.symbol.file");
@@ -526,7 +531,7 @@
archive = new ZipArchive(this, zdir);
} else {
archive = new ZipFileIndexArchive(this,
- ZipFileIndex.getZipFileIndex(zipFileName,
+ zipFileIndexCache.getZipFileIndex(zipFileName,
null,
usePreindexedCache,
preindexCacheLocation,
@@ -538,7 +543,7 @@
}
else {
archive = new ZipFileIndexArchive(this,
- ZipFileIndex.getZipFileIndex(zipFileName,
+ zipFileIndexCache.getZipFileIndex(zipFileName,
symbolFilePrefix,
usePreindexedCache,
preindexCacheLocation,
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Mon Jan 24 16:34:25 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Mon Jan 24 16:38:56 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,11 +38,9 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import java.util.zip.ZipException;
@@ -50,24 +48,28 @@
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.file.RelativePath.RelativeFile;
-/** This class implements building of index of a zip archive and access to it's context.
- * It also uses prebuild index if available. It supports invocations where it will
- * serialize an optimized zip index file to disk.
+/**
+ * This class implements the building of index of a zip archive and access to
+ * its context. It also uses a prebuilt index if available.
+ * It supports invocations where it will serialize an optimized zip index file
+ * to disk.
*
- * In oreder to use secondary index file make sure the option "usezipindex" is in the Options object,
- * when JavacFileManager is invoked. (You can pass "-XDusezipindex" on the command line.
+ * In order to use a secondary index file, set "usezipindex" in the Options
+ * object when JavacFileManager is invoked. (You can pass "-XDusezipindex" on
+ * the command line.)
*
- * Location where to look for/generate optimized zip index files can be provided using
- * "-XDcachezipindexdir=<directory>". If this flag is not provided, the dfault location is
- * the value of the "java.io.tmpdir" system property.
+ * Location where to look for/generate optimized zip index files can be
+ * provided using "-XDcachezipindexdir=<directory>". If this flag is not
+ * provided, the default location is the value of the "java.io.tmpdir" system
+ * property.
*
- * If key "-XDwritezipindexfiles" is specified, there will be new optimized index file
- * created for each archive, used by the compiler for compilation, at location,
- * specified by "cachezipindexdir" option.
+ * If "-XDwritezipindexfiles" is specified, there will be new optimized index
+ * file created for each archive, used by the compiler for compilation, at the
+ * location specified by the "cachezipindexdir" option.
*
- * If nonBatchMode option is specified (-XDnonBatchMode) the compiler will use timestamp
- * checking to reindex the zip files if it is needed. In batch mode the timestamps are not checked
- * and the compiler uses the cached indexes.
+ * If system property nonBatchMode option is specified the compiler will use
+ * timestamp checking to reindex the zip files if it is needed. In batch mode
+ * the timestamps are not checked and the compiler uses the cached indexes.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@@ -80,18 +82,18 @@
public final static long NOT_MODIFIED = Long.MIN_VALUE;
- private static Map<File, ZipFileIndex> zipFileIndexCache = new HashMap<File, ZipFileIndex>();
- private static ReentrantLock lock = new ReentrantLock();
private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
- private Map<RelativeDirectory, DirectoryEntry> directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
- private Set<RelativeDirectory> allDirs = Collections.<RelativeDirectory>emptySet();
+ private Map<RelativeDirectory, DirectoryEntry> directories =
+ Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
+ private Set<RelativeDirectory> allDirs =
+ Collections.<RelativeDirectory>emptySet();
// ZipFileIndex data entries
- private File zipFile;
+ final File zipFile;
private Reference<File> absFileRef;
- private long zipFileLastModified = NOT_MODIFIED;
+ long zipFileLastModified = NOT_MODIFIED;
private RandomAccessFile zipRandomFile;
private Entry[] entries;
@@ -99,156 +101,24 @@
private File zipIndexFile = null;
private boolean triedToReadIndex = false;
final RelativeDirectory symbolFilePrefix;
- private int symbolFilePrefixLength = 0;
+ private final int symbolFilePrefixLength;
private boolean hasPopulatedData = false;
- private long lastReferenceTimeStamp = NOT_MODIFIED;
+ long lastReferenceTimeStamp = NOT_MODIFIED;
- private boolean usePreindexedCache = false;
- private String preindexedCacheLocation = null;
+ private final boolean usePreindexedCache;
+ private final String preindexedCacheLocation;
private boolean writeIndex = false;
- private Map <String, SoftReference<RelativeDirectory>> relativeDirectoryCache =
+ private Map<String, SoftReference<RelativeDirectory>> relativeDirectoryCache =
new HashMap<String, SoftReference<RelativeDirectory>>();
- /**
- * Returns a list of all ZipFileIndex entries
- *
- * @return A list of ZipFileIndex entries, or an empty list
- */
- public static List<ZipFileIndex> getZipFileIndexes() {
- return getZipFileIndexes(false);
- }
- /**
- * Returns a list of all ZipFileIndex entries
- *
- * @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise
- * all ZipFileEntry(s) are included into the list.
- * @return A list of ZipFileIndex entries, or an empty list
- */
- public static List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) {
- List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>();
- lock.lock();
- try {
- zipFileIndexes.addAll(zipFileIndexCache.values());
-
- if (openedOnly) {
- for(ZipFileIndex elem : zipFileIndexes) {
- if (!elem.isOpen()) {
- zipFileIndexes.remove(elem);
- }
- }
- }
- }
- finally {
- lock.unlock();
- }
- return zipFileIndexes;
- }
-
- public boolean isOpen() {
- lock.lock();
- try {
- return zipRandomFile != null;
- }
- finally {
- lock.unlock();
- }
- }
-
- public static ZipFileIndex getZipFileIndex(File zipFile,
- RelativeDirectory symbolFilePrefix,
- boolean useCache, String cacheLocation,
- boolean writeIndex) throws IOException {
- ZipFileIndex zi = null;
- lock.lock();
- try {
- zi = getExistingZipIndex(zipFile);
-
- if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
- zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
- useCache, cacheLocation);
- zipFileIndexCache.put(zipFile, zi);
- }
- }
- finally {
- lock.unlock();
- }
- return zi;
+ public synchronized boolean isOpen() {
+ return (zipRandomFile != null);
}
- public static ZipFileIndex getExistingZipIndex(File zipFile) {
- lock.lock();
- try {
- return zipFileIndexCache.get(zipFile);
- }
- finally {
- lock.unlock();
- }
- }
-
- public static void clearCache() {
- lock.lock();
- try {
- zipFileIndexCache.clear();
- }
- finally {
- lock.unlock();
- }
- }
-
- public static void clearCache(long timeNotUsed) {
- lock.lock();
- try {
- Iterator<File> cachedFileIterator = zipFileIndexCache.keySet().iterator();
- while (cachedFileIterator.hasNext()) {
- File cachedFile = cachedFileIterator.next();
- ZipFileIndex cachedZipIndex = zipFileIndexCache.get(cachedFile);
- if (cachedZipIndex != null) {
- long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
- if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow...
- System.currentTimeMillis() > timeToTest) {
- zipFileIndexCache.remove(cachedFile);
- }
- }
- }
- }
- finally {
- lock.unlock();
- }
- }
-
- public static void removeFromCache(File file) {
- lock.lock();
- try {
- zipFileIndexCache.remove(file);
- }
- finally {
- lock.unlock();
- }
- }
-
- /** Sets already opened list of ZipFileIndexes from an outside client
- * of the compiler. This functionality should be used in a non-batch clients of the compiler.
- */
- public static void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException {
- lock.lock();
- try {
- if (zipFileIndexCache.isEmpty()) {
- throw new IllegalStateException("Setting opened indexes should be called only when the ZipFileCache is empty. Call JavacFileManager.flush() before calling this method.");
- }
-
- for (ZipFileIndex zfi : indexes) {
- zipFileIndexCache.put(zfi.zipFile, zfi);
- }
- }
- finally {
- lock.unlock();
- }
- }
-
- private ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
+ ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
boolean useCache, String cacheLocation) throws IOException {
this.zipFile = zipFile;
this.symbolFilePrefix = symbolFilePrefix;
@@ -266,19 +136,22 @@
checkIndex();
}
+ @Override
public String toString() {
return "ZipFileIndex[" + zipFile + "]";
}
// Just in case...
- protected void finalize() {
+ @Override
+ protected void finalize() throws Throwable {
closeFile();
+ super.finalize();
}
private boolean isUpToDate() {
- if (zipFile != null &&
- ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified()) &&
- hasPopulatedData) {
+ if (zipFile != null
+ && ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified())
+ && hasPopulatedData) {
return true;
}
@@ -339,15 +212,9 @@
allDirs = Collections.<RelativeDirectory>emptySet();
}
- public void close() {
- lock.lock();
- try {
- writeIndex();
- closeFile();
- }
- finally {
- lock.unlock();
- }
+ public synchronized void close() {
+ writeIndex();
+ closeFile();
}
private void closeFile() {
@@ -361,29 +228,24 @@
}
/**
- * Returns the ZipFileIndexEntry for an absolute path, if there is one.
+ * Returns the ZipFileIndexEntry for a path, if there is one.
*/
- Entry getZipIndexEntry(RelativePath path) {
- lock.lock();
+ synchronized Entry getZipIndexEntry(RelativePath path) {
try {
checkIndex();
DirectoryEntry de = directories.get(path.dirname());
String lookFor = path.basename();
- return de == null ? null : de.getEntry(lookFor);
+ return (de == null) ? null : de.getEntry(lookFor);
}
catch (IOException e) {
return null;
}
- finally {
- lock.unlock();
- }
}
/**
- * Returns a javac List of filenames within an absolute path in the ZipFileIndex.
+ * Returns a javac List of filenames within a directory in the ZipFileIndex.
*/
- public com.sun.tools.javac.util.List<String> getFiles(RelativeDirectory path) {
- lock.lock();
+ public synchronized com.sun.tools.javac.util.List<String> getFiles(RelativeDirectory path) {
try {
checkIndex();
@@ -398,13 +260,9 @@
catch (IOException e) {
return com.sun.tools.javac.util.List.<String>nil();
}
- finally {
- lock.unlock();
- }
}
- public List<String> getDirectories(RelativeDirectory path) {
- lock.lock();
+ public synchronized List<String> getDirectories(RelativeDirectory path) {
try {
checkIndex();
@@ -420,13 +278,9 @@
catch (IOException e) {
return com.sun.tools.javac.util.List.<String>nil();
}
- finally {
- lock.unlock();
- }
}
- public Set<RelativeDirectory> getAllDirectories() {
- lock.lock();
+ public synchronized Set<RelativeDirectory> getAllDirectories() {
try {
checkIndex();
if (allDirs == Collections.EMPTY_SET) {
@@ -438,9 +292,6 @@
catch (IOException e) {
return Collections.<RelativeDirectory>emptySet();
}
- finally {
- lock.unlock();
- }
}
/**
@@ -450,8 +301,7 @@
* @param path A path within the zip.
* @return True if the path is a file or dir, false otherwise.
*/
- public boolean contains(RelativePath path) {
- lock.lock();
+ public synchronized boolean contains(RelativePath path) {
try {
checkIndex();
return getZipIndexEntry(path) != null;
@@ -459,114 +309,69 @@
catch (IOException e) {
return false;
}
- finally {
- lock.unlock();
+ }
+
+ public synchronized boolean isDirectory(RelativePath path) throws IOException {
+ // The top level in a zip file is always a directory.
+ if (path.getPath().length() == 0) {
+ lastReferenceTimeStamp = System.currentTimeMillis();
+ return true;
}
+
+ checkIndex();
+ return directories.get(path) != null;
}
- public boolean isDirectory(RelativePath path) throws IOException {
- lock.lock();
- try {
- // The top level in a zip file is always a directory.
- if (path.getPath().length() == 0) {
- lastReferenceTimeStamp = System.currentTimeMillis();
- return true;
- }
-
- checkIndex();
- return directories.get(path) != null;
- }
- finally {
- lock.unlock();
- }
+ public synchronized long getLastModified(RelativeFile path) throws IOException {
+ Entry entry = getZipIndexEntry(path);
+ if (entry == null)
+ throw new FileNotFoundException();
+ return entry.getLastModified();
}
- public long getLastModified(RelativeFile path) throws IOException {
- lock.lock();
- try {
- Entry entry = getZipIndexEntry(path);
- if (entry == null)
- throw new FileNotFoundException();
- return entry.getLastModified();
+ public synchronized int length(RelativeFile path) throws IOException {
+ Entry entry = getZipIndexEntry(path);
+ if (entry == null)
+ throw new FileNotFoundException();
+
+ if (entry.isDir) {
+ return 0;
}
- finally {
- lock.unlock();
+
+ byte[] header = getHeader(entry);
+ // entry is not compressed?
+ if (get2ByteLittleEndian(header, 8) == 0) {
+ return entry.compressedSize;
+ } else {
+ return entry.size;
}
}
- public int length(RelativeFile path) throws IOException {
- lock.lock();
- try {
- Entry entry = getZipIndexEntry(path);
- if (entry == null)
- throw new FileNotFoundException();
-
- if (entry.isDir) {
- return 0;
- }
-
- byte[] header = getHeader(entry);
- // entry is not compressed?
- if (get2ByteLittleEndian(header, 8) == 0) {
- return entry.compressedSize;
- } else {
- return entry.size;
- }
- }
- finally {
- lock.unlock();
- }
- }
-
- public byte[] read(RelativeFile path) throws IOException {
- lock.lock();
- try {
- Entry entry = getZipIndexEntry(path);
- if (entry == null)
- throw new FileNotFoundException("Path not found in ZIP: " + path.path);
- return read(entry);
- }
- finally {
- lock.unlock();
- }
+ public synchronized byte[] read(RelativeFile path) throws IOException {
+ Entry entry = getZipIndexEntry(path);
+ if (entry == null)
+ throw new FileNotFoundException("Path not found in ZIP: " + path.path);
+ return read(entry);
}
- byte[] read(Entry entry) throws IOException {
- lock.lock();
- try {
- openFile();
- byte[] result = readBytes(entry);
- closeFile();
- return result;
- }
- finally {
- lock.unlock();
- }
+ synchronized byte[] read(Entry entry) throws IOException {
+ openFile();
+ byte[] result = readBytes(entry);
+ closeFile();
+ return result;
}
- public int read(RelativeFile path, byte[] buffer) throws IOException {
- lock.lock();
- try {
- Entry entry = getZipIndexEntry(path);
- if (entry == null)
- throw new FileNotFoundException();
- return read(entry, buffer);
- }
- finally {
- lock.unlock();
- }
+ public synchronized int read(RelativeFile path, byte[] buffer) throws IOException {
+ Entry entry = getZipIndexEntry(path);
+ if (entry == null)
+ throw new FileNotFoundException();
+ return read(entry, buffer);
}
- int read(Entry entry, byte[] buffer)
+ synchronized int read(Entry entry, byte[] buffer)
throws IOException {
- lock.lock();
- try {
- int result = readBytes(entry, buffer);
- return result;
- }
- finally {
- lock.unlock();
- }
+ int result = readBytes(entry, buffer);
+ return result;
}
private byte[] readBytes(Entry entry) throws IOException {
@@ -638,21 +443,20 @@
/*
* Inflate using the java.util.zip.Inflater class
*/
- private static Inflater inflater;
+ private SoftReference<Inflater> inflaterRef;
private int inflate(byte[] src, byte[] dest) {
+ Inflater inflater = (inflaterRef == null ? null : inflaterRef.get());
// construct the inflater object or reuse an existing one
if (inflater == null)
- inflater = new Inflater(true);
+ inflaterRef = new SoftReference<Inflater>(inflater = new Inflater(true));
- synchronized (inflater) {
- inflater.reset();
- inflater.setInput(src);
- try {
- return inflater.inflate(dest);
- } catch (DataFormatException ex) {
- return -1;
- }
+ inflater.reset();
+ inflater.setInput(src);
+ try {
+ return inflater.inflate(dest);
+ } catch (DataFormatException ex) {
+ return -1;
}
}
@@ -855,14 +659,10 @@
* @return long
*/
public long getZipFileLastModified() throws IOException {
- lock.lock();
- try {
+ synchronized (this) {
checkIndex();
return zipFileLastModified;
}
- finally {
- lock.unlock();
- }
}
/** ------------------------------------------------------------------------
@@ -1028,8 +828,7 @@
}
boolean ret = false;
- lock.lock();
- try {
+ synchronized (this) {
triedToReadIndex = true;
RandomAccessFile raf = null;
try {
@@ -1071,9 +870,6 @@
readFromIndex = true;
}
}
- finally {
- lock.unlock();
- }
return ret;
}
@@ -1144,8 +940,8 @@
raf.seek(currFP);
// Now write each of the files in the DirectoryEntry
- List<Entry> entries = de.getEntriesAsCollection();
- for (Entry zfie : entries) {
+ List<Entry> list = de.getEntriesAsCollection();
+ for (Entry zfie : list) {
// Write the name bytes
byte [] zfieNameBytes = zfie.name.getBytes("UTF-8");
int zfieNameBytesLen = zfieNameBytes.length;
@@ -1191,13 +987,9 @@
}
public boolean writeZipIndex() {
- lock.lock();
- try {
+ synchronized (this) {
return writeIndex();
}
- finally {
- lock.unlock();
- }
}
private File getIndexFile() {
@@ -1328,7 +1120,7 @@
return hash;
}
-
+ @Override
public String toString() {
return isDir ? ("Dir:" + dir + " : " + name) :
(dir + ":" + name);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexCache.java Mon Jan 24 16:38:56 2011 -0800
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.file;
+
+import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
+import com.sun.tools.javac.util.Context;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+/** A cache for ZipFileIndex objects. */
+public class ZipFileIndexCache {
+
+ private final Map<File, ZipFileIndex> map =
+ new HashMap<File, ZipFileIndex>();
+
+ /** Get a shared instance of the cache. */
+ private static ZipFileIndexCache sharedInstance;
+ public synchronized static ZipFileIndexCache getSharedInstance() {
+ if (sharedInstance == null)
+ sharedInstance = new ZipFileIndexCache();
+ return sharedInstance;
+ }
+
+ /** Get a context-specific instance of a cache. */
+ public static ZipFileIndexCache instance(Context context) {
+ ZipFileIndexCache instance = context.get(ZipFileIndexCache.class);
+ if (instance == null)
+ context.put(ZipFileIndexCache.class, instance = new ZipFileIndexCache());
+ return instance;
+ }
+
+ /**
+ * Returns a list of all ZipFileIndex entries
+ *
+ * @return A list of ZipFileIndex entries, or an empty list
+ */
+ public List<ZipFileIndex> getZipFileIndexes() {
+ return getZipFileIndexes(false);
+ }
+
+ /**
+ * Returns a list of all ZipFileIndex entries
+ *
+ * @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise
+ * all ZipFileEntry(s) are included into the list.
+ * @return A list of ZipFileIndex entries, or an empty list
+ */
+ public synchronized List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) {
+ List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>();
+
+ zipFileIndexes.addAll(map.values());
+
+ if (openedOnly) {
+ for(ZipFileIndex elem : zipFileIndexes) {
+ if (!elem.isOpen()) {
+ zipFileIndexes.remove(elem);
+ }
+ }
+ }
+
+ return zipFileIndexes;
+ }
+
+ public synchronized ZipFileIndex getZipFileIndex(File zipFile,
+ RelativeDirectory symbolFilePrefix,
+ boolean useCache, String cacheLocation,
+ boolean writeIndex) throws IOException {
+ ZipFileIndex zi = getExistingZipIndex(zipFile);
+
+ if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
+ zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
+ useCache, cacheLocation);
+ map.put(zipFile, zi);
+ }
+ return zi;
+ }
+
+ public synchronized ZipFileIndex getExistingZipIndex(File zipFile) {
+ return map.get(zipFile);
+ }
+
+ public synchronized void clearCache() {
+ map.clear();
+ }
+
+ public synchronized void clearCache(long timeNotUsed) {
+ Iterator<File> cachedFileIterator = map.keySet().iterator();
+ while (cachedFileIterator.hasNext()) {
+ File cachedFile = cachedFileIterator.next();
+ ZipFileIndex cachedZipIndex = map.get(cachedFile);
+ if (cachedZipIndex != null) {
+ long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
+ if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow...
+ System.currentTimeMillis() > timeToTest) {
+ map.remove(cachedFile);
+ }
+ }
+ }
+ }
+
+ public synchronized void removeFromCache(File file) {
+ map.remove(file);
+ }
+
+ /** Sets already opened list of ZipFileIndexes from an outside client
+ * of the compiler. This functionality should be used in a non-batch clients of the compiler.
+ */
+ public synchronized void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException {
+ if (map.isEmpty()) {
+ String msg =
+ "Setting opened indexes should be called only when the ZipFileCache is empty. "
+ + "Call JavacFileManager.flush() before calling this method.";
+ throw new IllegalStateException(msg);
+ }
+
+ for (ZipFileIndex zfi : indexes) {
+ map.put(zfi.zipFile, zfi);
+ }
+ }
+}
--- a/langtools/test/tools/javac/T6725036.java Mon Jan 24 16:34:25 2011 -0800
+++ b/langtools/test/tools/javac/T6725036.java Mon Jan 24 16:38:56 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
import com.sun.tools.javac.file.RelativePath.RelativeFile;
import com.sun.tools.javac.file.ZipFileIndex;
import com.sun.tools.javac.file.ZipFileIndexArchive;
+import com.sun.tools.javac.file.ZipFileIndexCache;
import com.sun.tools.javac.util.Context;
public class T6725036 {
@@ -57,8 +58,8 @@
JarEntry je = j.getJarEntry(TEST_ENTRY_NAME.getPath());
long jarEntryTime = je.getTime();
- ZipFileIndex zfi =
- ZipFileIndex.getZipFileIndex(rt_jar, null, false, null, false);
+ ZipFileIndexCache zfic = ZipFileIndexCache.getSharedInstance();
+ ZipFileIndex zfi = zfic.getZipFileIndex(rt_jar, null, false, null, false);
long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME);
check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime);