Add a buffered input stream when reading persistent unit cache
Make -Dgwt.persistentunitcachedir override the default cache dir if set.
Fail fast if we can't reate a file in the cache directory
Better test to see if directory exists before trying to start the cache.
Added a few more unit tests
Review at http://gwt-code-reviews.appspot.com/1386807
Review by: scottb@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9904 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java b/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java
index 6a7a408..38cb2ac 100644
--- a/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java
+++ b/dev/core/src/com/google/gwt/dev/javac/PersistentUnitCache.java
@@ -22,6 +22,7 @@
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.util.tools.Utility;
+import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.File;
@@ -43,13 +44,13 @@
* A class that manages a persistent cache of {@link CompilationUnit} instances.
* Writes out {@CompilationUnit} instances to a cache in a
* background thread.
- *
+ * <p>
* The persistent cache is implemented as a directory of log files with a date
* timestamp. A new log file gets created each time a new PersistentUnitCache is
* instantiated, (once per invocation of the compiler or DevMode). The design is
* intended to support only a single PersistentUnitCache instance in the
* compiler at a time.
- *
+ * <p>
* As new units are compiled, the cache data is appended to a log. This allows
* Java serialization to efficiently store references. The next time the cache
* is started, all logs are replayed and loaded into the cache in chronological
@@ -59,7 +60,8 @@
* {@link PersistentUnitCache#CACHE_FILE_THRESHOLD} , the cache files are
* consolidated back into a single file.
*
- * System Properties:
+ * <p>
+ * System Properties (see {@link UnitCacheFactory}).
*
* <ul>
* <li>gwt.persistentunitcache : enables the persistent cache (eventually will
@@ -67,6 +69,7 @@
* <li>gwt.persistentunitcachedir=<dir>: sets or overrides the cache directory</li>
* </ul>
*
+ * <p>
* Known Issues:
*
* <ul>
@@ -292,7 +295,7 @@
logger.log(TreeLogger.TRACE, "Persistent unit cache dir set to: "
+ this.cacheDirectory.getAbsolutePath());
- if (!cacheDirectory.exists() && !cacheDirectory.mkdir()) {
+ if (!cacheDirectory.isDirectory() && !cacheDirectory.mkdir()) {
logger.log(TreeLogger.ERROR, "Unable to initialize cache. Couldn't create directory "
+ cacheDirectory.getAbsolutePath() + ".");
throw new UnableToCompleteException();
@@ -308,7 +311,9 @@
try {
currentCacheFile.createNewFile();
} catch (IOException ex) {
- // ignore, we'll try again later in the writer thread.
+ logger.log(TreeLogger.ERROR, "Unable to create new cache log file "
+ + currentCacheFile.getAbsolutePath() + ".", ex);
+ throw new UnableToCompleteException();
}
unitCacheMapLoader = new UnitCacheMapLoader(logger);
@@ -444,17 +449,19 @@
File[] files = getCacheFiles();
for (File cacheFile : files) {
FileInputStream fis = null;
+ BufferedInputStream bis = null;
ObjectInputStream inputStream = null;
if (cacheFile.equals(currentCacheFile)) {
continue;
}
try {
fis = new FileInputStream(cacheFile);
+ bis = new BufferedInputStream(fis);
/*
* It is possible for the next call to throw an exception, leaving
* inputStream null and fis still live.
*/
- inputStream = new ObjectInputStream(fis);
+ inputStream = new ObjectInputStream(bis);
while (true) {
CompilationUnit unit = (CompilationUnit) inputStream.readObject();
if (unit == null) {
@@ -481,6 +488,7 @@
+ cacheFile.getAbsolutePath(), ex);
} finally {
Utility.close(inputStream);
+ Utility.close(bis);
Utility.close(fis);
logger.log(TreeLogger.TRACE, cacheFile.getName() + ": Load complete");
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/UnitCacheFactory.java b/dev/core/src/com/google/gwt/dev/javac/UnitCacheFactory.java
index 0bb1790..8083790 100644
--- a/dev/core/src/com/google/gwt/dev/javac/UnitCacheFactory.java
+++ b/dev/core/src/com/google/gwt/dev/javac/UnitCacheFactory.java
@@ -45,15 +45,13 @@
assert logger != null;
if (instance == null) {
if (usePersistent) {
- if (cacheDir == null) {
- String dirProp = "gwt.persistentunitcachedir";
- String propertyCacheDir = System.getProperty(dirProp);
- if (propertyCacheDir != null) {
- cacheDir = new File(propertyCacheDir);
- } else {
- throw new IllegalArgumentException("Expected " + dirProp
- + " system property to be set.");
- }
+ String dirProp = "gwt.persistentunitcachedir";
+ String propertyCacheDir = System.getProperty(dirProp);
+ if (propertyCacheDir != null) {
+ cacheDir = new File(propertyCacheDir);
+ } else if (cacheDir == null) {
+ throw new IllegalArgumentException("Expected " + dirProp
+ + " system property to be set.");
}
instance = new PersistentUnitCache(logger, cacheDir);
} else {
diff --git a/dev/core/test/com/google/gwt/dev/javac/PersistentUnitCacheTest.java b/dev/core/test/com/google/gwt/dev/javac/PersistentUnitCacheTest.java
index a736710..d34ce1b 100644
--- a/dev/core/test/com/google/gwt/dev/javac/PersistentUnitCacheTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/PersistentUnitCacheTest.java
@@ -38,6 +38,31 @@
lastCacheDir = null;
}
+ public void testBadDir() {
+ TreeLogger logger = TreeLogger.NULL;
+ File badDir = new File("sHoUlDnOtExi57");
+ try {
+ new PersistentUnitCache(logger, badDir);
+ fail("Expected an exception to be thrown");
+ } catch (UnableToCompleteException expected) {
+ }
+ }
+
+ /**
+ * Test if a file already exists with the name we want to put the
+ * cache dir in.
+ */
+ public void testFileInTheWay() throws IOException {
+ TreeLogger logger = TreeLogger.NULL;
+ File fileInTheWay = File.createTempFile("PersistentUnitTest-inTheWay", "");
+ fileInTheWay.deleteOnExit();
+ try {
+ new PersistentUnitCache(logger, fileInTheWay);
+ fail("Expected an exception to be thrown");
+ } catch (UnableToCompleteException expected) {
+ }
+ }
+
public void testPersistentCache() throws IOException, InterruptedException,
UnableToCompleteException {
TreeLogger logger = TreeLogger.NULL;
@@ -170,20 +195,6 @@
assertNumCacheFiles(unitCacheDir, 1);
}
- public void testBadDir() {
- TreeLogger logger = TreeLogger.NULL;
- File badDir = new File("sHoUlDnOtExi57");
- boolean caught = false;
- try {
- PersistentUnitCache puc = new PersistentUnitCache(logger, badDir);
- } catch (UnableToCompleteException ex) {
- // expected
- caught = true;
- } finally {
- assertTrue("Did not catch UnableToCompleteException", caught);
- }
- }
-
private void assertNumCacheFiles(File unitCacheDir, int expected) {
assertEquals(expected, unitCacheDir.list().length);
}