Hi!
While trying to implement my own mod of MessageInterpolator, stumbled on ResourceBundleMessageInterpolator cache. As is written in
Java6SE API, WeakHashMap, which is used for cache, is not thread-safe. And I haven't seen any synchronization routines in the code. Version 4.1.0.Final:
Code:
/**
* Resource bundle backed message interpolator.
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
* @author Gunnar Morling
*/
public class ResourceBundleMessageInterpolator implements MessageInterpolator {
// ...
/**
* Step 1-3 of message interpolation can be cached. We do this in this map.
*/
private final Map<LocalisedMessage, String> resolvedMessages = new WeakHashMap<LocalisedMessage, String>();
/**
* Flag indicating whether this interpolator should chance some of the interpolation steps.
*/
private final boolean cacheMessages;
public ResourceBundleMessageInterpolator() {
this( null );
}
public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator) {
this( userResourceBundleLocator, true );
}
public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator, boolean cacheMessages) {
defaultLocale = Locale.getDefault();
if ( userResourceBundleLocator == null ) {
this.userResourceBundleLocator = new PlatformResourceBundleLocator( USER_VALIDATION_MESSAGES );
}
else {
this.userResourceBundleLocator = userResourceBundleLocator;
}
this.defaultResourceBundleLocator = new PlatformResourceBundleLocator( DEFAULT_VALIDATION_MESSAGES );
this.cacheMessages = cacheMessages;
}
// ...
private String interpolateMessage(String message, Map<String, Object> annotationParameters, Locale locale) {
LocalisedMessage localisedMessage = new LocalisedMessage( message, locale );
String resolvedMessage = null;
if ( cacheMessages ) {
resolvedMessage = resolvedMessages.get( localisedMessage );
}
// ...
if ( cacheMessages ) {
resolvedMessages.put( localisedMessage, resolvedMessage );
}
// ...
}
// ...
}
So I'm guessing:
Is there some thread-safety magic in WeakHashMap (sorry, I'm a newbie in Java)?
Or is it (cache) is a short living one (since it's not static), and each MessageInterpolator is for single-threaded use only?
Or is it MessageInterpolator synchronized somewhere else (which would be kinda inefficient)?
Or is this cache never used?