Class WeakHashtable

java.lang.Object
java.util.Dictionary<K,​V>
java.util.Hashtable
org.apache.commons.logging.impl.WeakHashtable
All Implemented Interfaces:
Serializable, Cloneable, Map

public final class WeakHashtable
extends Hashtable

Implementation of Hashtable that uses WeakReference's to hold its keys thus allowing them to be reclaimed by the garbage collector. The associated values are retained using strong references.

This class follows the symantics of Hashtable as closely as possible. It therefore does not accept null values or keys.

Note: This is not intended to be a general purpose hash table replacement. This implementation is also tuned towards a particular purpose: for use as a replacement for Hashtable in LogFactory. This application requires good liveliness for get and put. Various tradeoffs have been made with this in mind.

Usage: typical use case is as a drop-in replacement for the Hashtable used in LogFactory for J2EE enviroments running 1.3+ JVMs. Use of this class in most cases (see below) will allow classloaders to be collected by the garbage collector without the need to call LogFactory.release(ClassLoader).

org.apache.commons.logging.LogFactory checks whether this class can be supported by the current JVM, and if so then uses it to store references to the LogFactory implementationd it loads (rather than using a standard Hashtable instance). Having this class used instead of Hashtable solves certain issues related to dynamic reloading of applications in J2EE-style environments. However this class requires java 1.3 or later (due to its use of java.lang.ref.WeakReference and associates). And by the way, this extends Hashtable rather than HashMap for backwards compatibility reasons. See the documentation for method LogFactory.createFactoryStore for more details.

The reason all this is necessary is due to a issue which arises during hot deploy in a J2EE-like containers. Each component running in the container owns one or more classloaders; when the component loads a LogFactory instance via the component classloader a reference to it gets stored in the static LogFactory.factories member, keyed by the component's classloader so different components don't stomp on each other. When the component is later unloaded, the container sets the component's classloader to null with the intent that all the component's classes get garbage-collected. However there's still a reference to the component's classloader from a key in the "global" LogFactory's factories member! If LogFactory.release() is called whenever component is unloaded, the classloaders will be correctly garbage collected; this should be done by any container that bundles commons-logging by default. However, holding the classloader references weakly ensures that the classloader will be garbage collected without the container performing this step.

Limitations: There is still one (unusual) scenario in which a component will not be correctly unloaded without an explicit release. Though weak references are used for its keys, it is necessary to use strong references for its values.

If the abstract class LogFactory is loaded by the container classloader but a subclass of LogFactory [LogFactory1] is loaded by the component's classloader and an instance stored in the static map associated with the base LogFactory class, then there is a strong reference from the LogFactory class to the LogFactory1 instance (as normal) and a strong reference from the LogFactory1 instance to the component classloader via getClass().getClassLoader(). This chain of references will prevent collection of the child classloader.

Such a situation occurs when the commons-logging.jar is loaded by a parent classloader (e.g. a server level classloader in a servlet container) and a custom LogFactory implementation is loaded by a child classloader (e.g. a web app classloader).

To avoid this scenario, ensure that any custom LogFactory subclass is loaded by the same classloader as the base LogFactory. Creating custom LogFactory subclasses is, however, rare. The standard LogFactoryImpl class should be sufficient for most or all users.

Since:
1.1
Author:
Brian Stansberry
See Also:
Serialized Form
  • Constructor Summary

    Constructors
    Constructor Description
    WeakHashtable()
    Constructs a WeakHashtable with the Hashtable default capacity and load factor.
  • Method Summary

    Modifier and Type Method Description
    boolean containsKey​(Object key)
    Returns true if this Hashtable contains the specified object as a key of one of the key/value pairs.
    Enumeration elements()
    Returns an enumeration on the values of this Hashtable.
    Set entrySet()
    Returns a set of the mappings contained in this Hashtable.
    Object get​(Object key)
    Returns the value associated with the specified key in this Hashtable.
    boolean isEmpty()
    Returns true if this Hashtable has no key/value pairs.
    Enumeration keys()
    Returns an enumeration on the keys of this Hashtable instance.
    Set keySet()
    Returns a set of the keys contained in this Hashtable.
    Object put​(Object key, Object value)
    Associate the specified value with the specified key in this Hashtable.
    void putAll​(Map t)
    Copies every mapping to this Hashtable from the specified map.
    protected void rehash()
    Increases the capacity of this Hashtable.
    Object remove​(Object key)
    Removes the key/value pair with the specified key from this Hashtable.
    int size()
    Returns the number of key/value pairs in this Hashtable.
    String toString()
    Returns the string representation of this Hashtable.
    Collection values()
    Returns a collection of the values contained in this Hashtable.

    Methods inherited from class java.util.Hashtable

    clear, clone, contains, containsValue, equals, hashCode

    Methods inherited from class java.lang.Object

    finalize, getClass, notify, notifyAll, wait, wait, wait
  • Constructor Details

    • WeakHashtable

      public WeakHashtable()
      Constructs a WeakHashtable with the Hashtable default capacity and load factor.
  • Method Details

    • containsKey

      public boolean containsKey​(Object key)
      Description copied from class: Hashtable
      Returns true if this Hashtable contains the specified object as a key of one of the key/value pairs.
      Specified by:
      containsKey in interface Map
      Overrides:
      containsKey in class Hashtable
      Parameters:
      key - the object to look for as a key in this Hashtable.
      Returns:
      true if object is a key in this Hashtable, false otherwise.
      See Also:
      Hashtable
    • elements

      public Enumeration elements()
      Description copied from class: Hashtable
      Returns an enumeration on the values of this Hashtable. The results of the Enumeration may be affected if the contents of this Hashtable are modified.
      Overrides:
      elements in class Hashtable
      Returns:
      an enumeration of the values of this Hashtable.
      See Also:
      Hashtable
    • entrySet

      public Set entrySet()
      Description copied from class: Hashtable
      Returns a set of the mappings contained in this Hashtable. Each element in the set is a Map.Entry. The set is backed by this Hashtable so changes to one are reflected by the other. The set does not support adding.
      Specified by:
      entrySet in interface Map
      Overrides:
      entrySet in class Hashtable
      Returns:
      a set of the mappings.
      See Also:
      Hashtable
    • get

      public Object get​(Object key)
      Description copied from class: Hashtable
      Returns the value associated with the specified key in this Hashtable.
      Specified by:
      get in interface Map
      Overrides:
      get in class Hashtable
      Parameters:
      key - the key of the value returned.
      Returns:
      the value associated with the specified key, or null if the specified key does not exist.
      See Also:
      Hashtable
    • keys

      public Enumeration keys()
      Description copied from class: Hashtable
      Returns an enumeration on the keys of this Hashtable instance. The results of the enumeration may be affected if the contents of this Hashtable are modified.
      Overrides:
      keys in class Hashtable
      Returns:
      an enumeration of the keys of this Hashtable.
      See Also:
      Hashtable
    • keySet

      public Set keySet()
      Description copied from class: Hashtable
      Returns a set of the keys contained in this Hashtable. The set is backed by this Hashtable so changes to one are reflected by the other. The set does not support adding.
      Specified by:
      keySet in interface Map
      Overrides:
      keySet in class Hashtable
      Returns:
      a set of the keys.
      See Also:
      Hashtable
    • put

      public Object put​(Object key, Object value)
      Description copied from class: Hashtable
      Associate the specified value with the specified key in this Hashtable. If the key already exists, the old value is replaced. The key and value cannot be null.
      Specified by:
      put in interface Map
      Overrides:
      put in class Hashtable
      Parameters:
      key - the key to add.
      value - the value to add.
      Returns:
      the old value associated with the specified key, or null if the key did not exist.
      See Also:
      Hashtable
    • putAll

      public void putAll​(Map t)
      Description copied from class: Hashtable
      Copies every mapping to this Hashtable from the specified map.
      Specified by:
      putAll in interface Map
      Overrides:
      putAll in class Hashtable
      Parameters:
      t - the map to copy mappings from.
      See Also:
      Hashtable
    • values

      public Collection values()
      Description copied from class: Hashtable
      Returns a collection of the values contained in this Hashtable. The collection is backed by this Hashtable so changes to one are reflected by the other. The collection does not support adding.
      Specified by:
      values in interface Map
      Overrides:
      values in class Hashtable
      Returns:
      a collection of the values.
      See Also:
      Hashtable
    • remove

      public Object remove​(Object key)
      Description copied from class: Hashtable
      Removes the key/value pair with the specified key from this Hashtable.
      Specified by:
      remove in interface Map
      Overrides:
      remove in class Hashtable
      Parameters:
      key - the key to remove.
      Returns:
      the value associated with the specified key, or null if the specified key did not exist.
      See Also:
      Hashtable
    • isEmpty

      public boolean isEmpty()
      Description copied from class: Hashtable
      Returns true if this Hashtable has no key/value pairs.
      Specified by:
      isEmpty in interface Map
      Overrides:
      isEmpty in class Hashtable
      Returns:
      true if this Hashtable has no key/value pairs, false otherwise.
      See Also:
      Hashtable
    • size

      public int size()
      Description copied from class: Hashtable
      Returns the number of key/value pairs in this Hashtable.
      Specified by:
      size in interface Map
      Overrides:
      size in class Hashtable
      Returns:
      the number of key/value pairs in this Hashtable.
      See Also:
      Hashtable
    • toString

      public String toString()
      Description copied from class: Hashtable
      Returns the string representation of this Hashtable.
      Overrides:
      toString in class Hashtable
      Returns:
      the string representation of this Hashtable.
      See Also:
      Hashtable
    • rehash

      protected void rehash()
      Description copied from class: Hashtable
      Increases the capacity of this Hashtable. This method is called when the size of this Hashtable exceeds the load factor.
      Overrides:
      rehash in class Hashtable
      See Also:
      Hashtable