harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Li-Gang Wang (JIRA)" <j...@apache.org>
Subject [jira] Created: (HARMONY-3883) [classlib]WeakHashMap.keySet().toArray() intermittently throws NoSuchElementException in java.lang.ThreadTest of DRLVM kernel test
Date Thu, 17 May 2007 06:10:16 GMT
[classlib]WeakHashMap.keySet().toArray() intermittently throws NoSuchElementException in java.lang.ThreadTest
of DRLVM kernel test

                 Key: HARMONY-3883
                 URL: https://issues.apache.org/jira/browse/HARMONY-3883
             Project: Harmony
          Issue Type: Bug
          Components: Classlib
         Environment: win/linux 32/64
            Reporter: Li-Gang Wang

I found there is a design bug in WeakHashMap.keySet().toArray() .

WeakHashMap.keySet().toArray() inherits AbstractCollection.toArray(). Its implementation is
as follows:
	public Object[] toArray() {
		int size = size(), index = 0;
		Iterator<?> it = iterator();
		Object[] array = new Object[size];
		while (index < size) {
            array[index++] = it.next();
		return array;

After assigning 'size()' to 'size', the 'while' loop expects 'size' elements in the iterator
'it'. But actually GC might happen and clear some weak keys of the WeakHashMap instance in
the meantime. The iterator will skip the cleared weak keys in 'it.hasNext()' called by 'it.next()',
so the actual number of the elements in 'it' is smaller than 'size'. When 'it' runs out its
elements, 'it.next()' will throw a NoSuchElementException. Parts of HashIterator implementation
in WeakHashMap is as follows:
        public boolean hasNext() {
            if (nextEntry != null) {
                return true;
            while (true) {
                if (nextEntry == null) {
                    while (position < elementData.length) {
                        if ((nextEntry = elementData[position++]) != null) {
                    if (nextEntry == null) {
                        return false;
                // ensure key of next entry is not gc'ed
                nextKey = nextEntry.get();
                if (nextKey != null || nextEntry.isNull) {
                    return true;
                nextEntry = nextEntry.next;

        public R next() {
            if (expectedModCount == modCount) {
                if (hasNext()) {
                    currentEntry = nextEntry;
                    nextEntry = currentEntry.next;
                    R result = type.get(currentEntry);
                    // free the key
                    nextKey = null;
                    return result;
                throw new NoSuchElementException();
            throw new ConcurrentModificationException();

I suspect the intermittent failure in java.lang.ThreadTest may disappear if this bug is fixed.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message