Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4201900
Votes 0
Synopsis W:Hashtable.put() shouldn't reinvoke put() after rehash()
Category e_p_java:classes_util
Reported Against 3.0
Release Fixed
State 11-Closed, duplicate of 4089896, request for enhancement
Priority: 3-Medium
Related Bugs 4089896
Submit Date 09-JAN-1999
Description
WeakCache extends Hashtable and defines its own put() method that wraps
the  customer  reference in a weak reference  customer ; a reference to that
weak reference  customer  is what actually gets passed to Hashtable.put().

If Hashtable.put() has to grow the array, after it does so it
reinvokes put() to put the  customer  reference in the new array.
But that calls WeakCache.put(), not Hashtable.put(), and creates a
SECOND weak reference wrapper for its argument.  So you end up with
a weak reference to a weak reference to whatever it is you wanted in
the cache, and that's wrong; a get() won't return the original  customer .

The following simple test shows the problem:

import sun.misc.WeakCache;

public class WeakCacheTest {
    public static void main( String[] args ) {

        WeakCache cache = new WeakCache(10);
        int i;
        Integer j;

        // Add 20 items to the cache, causing it to expand.

        for ( i = 0; i < 20; i++ ) {
            j = new Integer( i );
            System.err.println( "putting " + i + " in cache" );
            cache.put( j, j );
        }
        System.err.println( "---------------------------------" );

        // Now read the items out again, casting back to Integer.
        // Number 11 (?) will fail the cast, since WeakCache.put() was
        // called recursively from Hashtable.put(), wrapping the
        // reference to the Integer in a second Ref.

        try {
            for ( i = 0; i < 20; i++ ) {
                System.err.println( "getting " + i + " from cache" );
                j = (Integer) cache.get( new Integer( i ) );
                System.err.println( "   value is " + j );
            }
            System.err.println( "---------------------------------" );
        } catch ( Exception e ) {
            System.err.println( "caught exception: " + e );
        }
    }
}

It yields this:

putting 0 in cache
putting 1 in cache
putting 2 in cache
putting 3 in cache
putting 4 in cache
putting 5 in cache
putting 6 in cache
putting 7 in cache
putting 8 in cache
putting 9 in cache
putting 10 in cache
putting 11 in cache
putting 12 in cache
putting 13 in cache
putting 14 in cache
putting 15 in cache
putting 16 in cache
putting 17 in cache
putting 18 in cache
putting 19 in cache
---------------------------------
getting 0 from cache
   value is 0
getting 1 from cache
   value is 1
getting 2 from cache
   value is 2
getting 3 from cache
   value is 3
getting 4 from cache
   value is 4
getting 5 from cache
   value is 5
getting 6 from cache
   value is 6
getting 7 from cache
caught exception: java.lang.ClassCastException: sun.misc.WeakCache$Value
Work Around
N/A
Evaluation
The same bug exists in JDK1.1.X.  See bug report 4089896.  This could be
considered a bug in WeakCache because it chooses to use subclassing
instead of delegation.

  xxxxx@xxxxx   1999-01-13

I'm changing this to an RFE, just like the JDK.

  xxxxx@xxxxx   1999-07-10
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang