ICU-11783 Remove use of class loaders in resource loading caches.

There is currently no known use-case where this code that is being
removed solves a real problem, but it causes problems in Android when
ICU4J is being initialized using one class loader but then called using
another class loader.

R=markus.icu@gmail.com, yoshito_umaoka@us.ibm.com

Review URL: https://codereview.appspot.com/260600044 .

X-SVN-Rev: 37920
This commit is contained in:
Fredrik Roubert 2015-09-09 18:42:45 +00:00
parent ac4466583f
commit d8a1859b6e
4 changed files with 32 additions and 51 deletions

View File

@ -1217,7 +1217,7 @@ public class ICUResourceBundle extends UResourceBundle {
localeName = ULocale.getBaseName(localeID);
}
String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);
ICUResourceBundle b = (ICUResourceBundle)loadFromCache(root, fullName, defaultLocale);
ICUResourceBundle b = (ICUResourceBundle)loadFromCache(fullName, defaultLocale);
// here we assume that java type resource bundle organization
// is required then the base name contains '.' else
@ -1249,7 +1249,7 @@ public class ICUResourceBundle extends UResourceBundle {
// for a bundle that does not have nofallback.
// Are the relevant test cases just disabled?
// Do item aliases not get followed via "direct" loading?
return addToCache(root, fullName, defaultLocale, b);
return addToCache(fullName, defaultLocale, b);
}
// fallback to locale ID parent
@ -1280,7 +1280,7 @@ public class ICUResourceBundle extends UResourceBundle {
localeName = b.getLocaleID();
int i = localeName.lastIndexOf('_');
b = (ICUResourceBundle)addToCache(root, fullName, defaultLocale, b);
b = (ICUResourceBundle)addToCache(fullName, defaultLocale, b);
// TODO: C++ uresbund.cpp also checks for %%ParentIsRoot. Why not Java?
String parentLocaleName = ((ICUResourceBundleImpl.ResourceTable)b).findString("%%Parent");

View File

@ -146,59 +146,56 @@ public final class ICUResourceBundleReader {
private static ReaderCache CACHE = new ReaderCache();
private static final ICUResourceBundleReader NULL_READER = new ICUResourceBundleReader();
private static class ReaderInfo {
private static class ReaderCacheKey {
final String baseName;
final String localeID;
final ClassLoader loader;
ReaderInfo(String baseName, String localeID, ClassLoader loader) {
ReaderCacheKey(String baseName, String localeID) {
this.baseName = (baseName == null) ? "" : baseName;
this.localeID = (localeID == null) ? "" : localeID;
this.loader = loader;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof ReaderInfo)) {
if (!(obj instanceof ReaderCacheKey)) {
return false;
}
ReaderInfo info = (ReaderInfo)obj;
ReaderCacheKey info = (ReaderCacheKey)obj;
return this.baseName.equals(info.baseName)
&& this.localeID.equals(info.localeID)
&& this.loader.equals(info.loader);
&& this.localeID.equals(info.localeID);
}
public int hashCode() {
return baseName.hashCode() ^ localeID.hashCode() ^ loader.hashCode();
return baseName.hashCode() ^ localeID.hashCode();
}
}
private static class ReaderCache extends SoftCache<ReaderInfo, ICUResourceBundleReader, ReaderInfo> {
private static class ReaderCache extends SoftCache<ReaderCacheKey, ICUResourceBundleReader, ClassLoader> {
/* (non-Javadoc)
* @see com.ibm.icu.impl.CacheBase#createInstance(java.lang.Object, java.lang.Object)
*/
@Override
protected ICUResourceBundleReader createInstance(ReaderInfo key, ReaderInfo data) {
String fullName = ICUResourceBundleReader.getFullName(data.baseName, data.localeID);
protected ICUResourceBundleReader createInstance(ReaderCacheKey key, ClassLoader loader) {
String fullName = ICUResourceBundleReader.getFullName(key.baseName, key.localeID);
try {
ByteBuffer inBytes;
if (data.baseName != null && data.baseName.startsWith(ICUData.ICU_BASE_NAME)) {
if (key.baseName != null && key.baseName.startsWith(ICUData.ICU_BASE_NAME)) {
String itemPath = fullName.substring(ICUData.ICU_BASE_NAME.length() + 1);
inBytes = ICUBinary.getData(data.loader, fullName, itemPath);
inBytes = ICUBinary.getData(loader, fullName, itemPath);
if (inBytes == null) {
return NULL_READER;
}
} else {
@SuppressWarnings("resource") // Closed by getByteBufferFromInputStreamAndCloseStream().
InputStream stream = ICUData.getStream(data.loader, fullName);
InputStream stream = ICUData.getStream(loader, fullName);
if (stream == null) {
return NULL_READER;
}
inBytes = ICUBinary.getByteBufferFromInputStreamAndCloseStream(stream);
}
return new ICUResourceBundleReader(inBytes, data.baseName, data.localeID, data.loader);
return new ICUResourceBundleReader(inBytes, key.baseName, key.localeID, loader);
} catch (IOException ex) {
throw new ICUUncheckedIOException("Data file " + fullName + " is corrupt - " + ex.getMessage(), ex);
}
@ -229,8 +226,8 @@ public final class ICUResourceBundleReader {
}
static ICUResourceBundleReader getReader(String baseName, String localeID, ClassLoader root) {
ReaderInfo info = new ReaderInfo(baseName, localeID, root);
ICUResourceBundleReader reader = CACHE.getInstance(info, info);
ReaderCacheKey info = new ReaderCacheKey(baseName, localeID);
ICUResourceBundleReader reader = CACHE.getInstance(info, root);
if (reader == NULL_READER) {
return null;
}

View File

@ -123,7 +123,7 @@ public class ResourceBundleWrapper extends UResourceBundle {
name = name + "_" + localeID;
}
ResourceBundleWrapper b = (ResourceBundleWrapper)loadFromCache(cl, name, defaultLocale);
ResourceBundleWrapper b = (ResourceBundleWrapper)loadFromCache(name, defaultLocale);
if(b==null){
ResourceBundleWrapper parent = null;
int i = localeID.lastIndexOf('_');
@ -131,12 +131,12 @@ public class ResourceBundleWrapper extends UResourceBundle {
boolean loadFromProperties = false;
if (i != -1) {
String locName = localeID.substring(0, i);
parent = (ResourceBundleWrapper)loadFromCache(cl, baseName+"_"+locName,defaultLocale);
parent = (ResourceBundleWrapper)loadFromCache(baseName+"_"+locName,defaultLocale);
if(parent == null){
parent = (ResourceBundleWrapper)instantiateBundle(baseName, locName , cl, disableFallback);
}
}else if(localeID.length()>0){
parent = (ResourceBundleWrapper)loadFromCache(cl, baseName,defaultLocale);
parent = (ResourceBundleWrapper)loadFromCache(baseName,defaultLocale);
if(parent==null){
parent = (ResourceBundleWrapper)instantiateBundle(baseName, "", cl, disableFallback);
}
@ -202,7 +202,7 @@ public class ResourceBundleWrapper extends UResourceBundle {
if (b==null) {
String defaultName = defaultLocale.toString();
if (localeID.length()>0 && localeID.indexOf('_')< 0 && defaultName.indexOf(localeID) == -1) {
b = (ResourceBundleWrapper)loadFromCache(cl,baseName+"_"+defaultName, defaultLocale);
b = (ResourceBundleWrapper)loadFromCache(baseName+"_"+defaultName, defaultLocale);
if(b==null){
b = (ResourceBundleWrapper)instantiateBundle(baseName , defaultName, cl, disableFallback);
}
@ -219,7 +219,7 @@ public class ResourceBundleWrapper extends UResourceBundle {
System.out.println(e);
}
}
b = (ResourceBundleWrapper)addToCache(cl, name, defaultLocale, b);
b = (ResourceBundleWrapper)addToCache(name, defaultLocale, b);
}
if(b!=null){

View File

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 2004-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2004-2015, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@ -348,10 +348,9 @@ public abstract class UResourceBundle extends ResourceBundle {
* @deprecated This API is ICU internal only.
*/
@Deprecated
protected static UResourceBundle addToCache(ClassLoader cl, String fullName,
ULocale defaultLocale, UResourceBundle b) {
protected static UResourceBundle addToCache(String fullName, ULocale defaultLocale, UResourceBundle b) {
synchronized(cacheKey){
cacheKey.setKeyValues(cl, fullName, defaultLocale);
cacheKey.setKeyValues(fullName, defaultLocale);
UResourceBundle cachedBundle = BUNDLE_CACHE.get(cacheKey);
if (cachedBundle != null) {
return cachedBundle;
@ -367,10 +366,9 @@ public abstract class UResourceBundle extends ResourceBundle {
* @deprecated This API is ICU internal only.
*/
@Deprecated
protected static UResourceBundle loadFromCache(ClassLoader cl, String fullName,
ULocale defaultLocale){
protected static UResourceBundle loadFromCache(String fullName, ULocale defaultLocale) {
synchronized(cacheKey){
cacheKey.setKeyValues(cl, fullName, defaultLocale);
cacheKey.setKeyValues(fullName, defaultLocale);
return BUNDLE_CACHE.get(cacheKey);
}
}
@ -386,7 +384,6 @@ public abstract class UResourceBundle extends ResourceBundle {
* locale (if at all).
*/
private static final class ResourceCacheKey implements Cloneable {
private SoftReference<ClassLoader> loaderRef;
private String searchName;
private ULocale defaultLocale;
private int hashCodeCache;
@ -418,13 +415,7 @@ public abstract class UResourceBundle extends ResourceBundle {
return false;
}
}
//are refs (both non-null) or (both null)?
if (loaderRef == null) {
return otherEntry.loaderRef == null;
} else {
return (otherEntry.loaderRef != null)
&& (loaderRef.get() == otherEntry.loaderRef.get());
}
return true;
} catch (NullPointerException e) {
return false;
} catch (ClassCastException e) {
@ -446,20 +437,13 @@ public abstract class UResourceBundle extends ResourceBundle {
}
///CLOVER:ON
private synchronized void setKeyValues(ClassLoader root, String searchName,
ULocale defaultLocale) {
private synchronized void setKeyValues(String searchName, ULocale defaultLocale) {
this.searchName = searchName;
hashCodeCache = searchName.hashCode();
this.defaultLocale = defaultLocale;
if (defaultLocale != null) {
hashCodeCache ^= defaultLocale.hashCode();
}
if (root == null) {
this.loaderRef = null;
} else {
loaderRef = new SoftReference<ClassLoader>(root);
hashCodeCache ^= root.hashCode();
}
}
/*private void clear() {
setKeyValues(null, "", null);
@ -556,7 +540,7 @@ public abstract class UResourceBundle extends ResourceBundle {
case ROOT_ICU:
if(disableFallback) {
String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);
b = loadFromCache(root, fullName, defaultLocale);
b = loadFromCache(fullName, defaultLocale);
if (b == null) {
b = ICUResourceBundle.getBundleInstance(baseName, localeName, root,
disableFallback);