aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormkoslacz <mateusz.koslacz@gmail.com>2015-03-16 17:14:54 +0100
committermkoslacz <mateusz.koslacz@gmail.com>2015-03-16 17:14:54 +0100
commit98a9d50ec4e466ee8d84be47e0a7bab6434e7d0f (patch)
tree182125de3eea74b331a533a05725b907d6d82880
parent912d561166483823dcf55d16c401f1f81536d7c6 (diff)
downloadAndroidAsync-98a9d50ec4e466ee8d84be47e0a7bab6434e7d0f.tar.gz
AndroidAsync-98a9d50ec4e466ee8d84be47e0a7bab6434e7d0f.tar.bz2
AndroidAsync-98a9d50ec4e466ee8d84be47e0a7bab6434e7d0f.zip
fix issue 461
I have managed to apply workaround to issue #461 mentioned here: https://github.com/koush/ion/issues/461 based on this commit https://github.com/candrews/HttpResponseCache/commit/a93c92d1d8b87778ac7bb2fa2fe2759e7ca06219 I use local copy of MessageDigest in com.koushikdutta.async.util.FileCache instead of getting instance of MessageDigest each time. It prevents from occuring java.util.ConcurrentModificationException at com.koushikdutta.async.util.FileCache.toKeyString().
-rw-r--r--AndroidAsync/src/com/koushikdutta/async/http/cache/ResponseCacheMiddleware.java4
-rw-r--r--AndroidAsync/src/com/koushikdutta/async/util/FileCache.java49
2 files changed, 36 insertions, 17 deletions
diff --git a/AndroidAsync/src/com/koushikdutta/async/http/cache/ResponseCacheMiddleware.java b/AndroidAsync/src/com/koushikdutta/async/http/cache/ResponseCacheMiddleware.java
index 614ba40..ee2a108 100644
--- a/AndroidAsync/src/com/koushikdutta/async/http/cache/ResponseCacheMiddleware.java
+++ b/AndroidAsync/src/com/koushikdutta/async/http/cache/ResponseCacheMiddleware.java
@@ -104,7 +104,7 @@ public class ResponseCacheMiddleware extends SimpleMiddleware {
return null;
}
- String key = FileCache.toKeyString(data.request.getUri());
+ String key = cache.toKeyString(data.request.getUri());
FileInputStream[] snapshot = null;
long contentLength;
Entry entry;
@@ -267,7 +267,7 @@ public class ResponseCacheMiddleware extends SimpleMiddleware {
return;
}
- String key = FileCache.toKeyString(data.request.getUri());
+ String key = cache.toKeyString(data.request.getUri());
RawHeaders varyHeaders = requestHeaders.getHeaders().getAll(networkResponse.getVaryFields());
Entry entry = new Entry(data.request.getUri(), varyHeaders, data.request, networkResponse.getHeaders());
BodyCacher cacher = new BodyCacher();
diff --git a/AndroidAsync/src/com/koushikdutta/async/util/FileCache.java b/AndroidAsync/src/com/koushikdutta/async/util/FileCache.java
index d117108..548924f 100644
--- a/AndroidAsync/src/com/koushikdutta/async/util/FileCache.java
+++ b/AndroidAsync/src/com/koushikdutta/async/util/FileCache.java
@@ -19,6 +19,9 @@ import java.util.Set;
* Created by koush on 4/12/14.
*/
public class FileCache {
+
+ private MessageDigest messageDigest;
+
class CacheEntry {
final long size;
public CacheEntry(File file) {
@@ -62,23 +65,16 @@ public class FileCache {
return null;
}
- public static String toKeyString(Object... parts) {
- MessageDigest messageDigest;
- synchronized (FileCache.class) {
- try {
- messageDigest = MessageDigest.getInstance(hashAlgorithm);
- } catch (NoSuchAlgorithmException e) {
- messageDigest = findAlternativeMessageDigest();
- if (null == messageDigest)
- throw new RuntimeException(e);
+ public String toKeyString(Object... parts) {
+ synchronized (FileCache.class) { // I spreaded synchronized block to whole method to assure
+ // that only one thread deals with our copy of MessageDigest
+ // instance
+ for (Object part : parts) {
+ messageDigest.update(part.toString().getBytes());
}
+ byte[] md5bytes = messageDigest.digest();
+ return new BigInteger(1, md5bytes).toString(16);
}
-
- for (Object part : parts) {
- messageDigest.update(part.toString().getBytes());
- }
- byte[] md5bytes = messageDigest.digest();
- return new BigInteger(1, md5bytes).toString(16);
}
boolean loadAsync;
@@ -275,10 +271,33 @@ public class FileCache {
this.loadAsync = loadAsync;
cache = new InternalCache();
+ try {
+ messageDigest = (MessageDigest) MessageDigest.getInstance(hashAlgorithm);
+ cloneMessageDigest(messageDigest);
+ } catch (NoSuchAlgorithmException e1) {
+ messageDigest = findAlternativeMessageDigest();
+ if (null == messageDigest)
+ throw new RuntimeException(e1);
+ cloneMessageDigest(messageDigest);
+ }
+
directory.mkdirs();
doLoad();
}
+ // taken from https://github.com/candrews/HttpResponseCache/commit/a93c92d1d8b87778ac7bb2fa2fe2759e7ca06219
+ private void cloneMessageDigest(MessageDigest messageDigest){
+ try {
+ // clone the messageDigest instance as a workaround for
+ // java.security.MessageDigest.getInstance(String) not being thread safe in Android
+ // see https://code.google.com/p/android/issues/detail?id=37937
+ messageDigest = (MessageDigest) messageDigest.clone();
+ } catch (CloneNotSupportedException e) {
+ // ignore the exception and use the original messageDigest.
+ // hopefully whatever platform we're on doesn't have the bug that requires the cloning workaround
+ }
+ }
+
public long size() {
return cache.size();
}