You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by "Uwe Schindler (JIRA)" <ji...@apache.org> on 2010/11/30 17:48:13 UTC

[jira] Updated: (HARMONY-6681) AbstractCollection.toArray() and AbstractCollection.toArray(T[]) are broken for concurrently modified collections like ConcurrentHashMap.keySet()

     [ https://issues.apache.org/jira/browse/HARMONY-6681?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Uwe Schindler updated HARMONY-6681:
-----------------------------------

    Description: 
If you call ConcurrentHashMap.keySet().toArray() [as done in trunks Lucene's RAMDirectory#fileMap] and another thread modifies the collecton, you get NoSuchElementExceptions or AIOOBEs. The reason is that AbstractCollection.toArray methods allocate the array using the current size of the collection and then either iterate on the values (which is oficially supported by ConcurrentHashMap, its iterator is safe for concurrent modification!) and set them on the target without checking bounds. On the other hand if there are too few entries in the collection, the array is nulled at the end. The bad thing is that the toArray() and toArray(T[]) methods behave differently, so depending on the modification they throw different exceptions (one impl simply drops entries that dont fit into the array).

Since Java SE 6, its officially documented, how toArray must behave: [http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray(T[])]; This is violated by harmony and even the fix in HARMONY-6236 does not respect it, leading to such bugs.

Java SE 5 does not document that, but ConcurrentHashMap.keySet(), values() and entrySet() have own implementations of toArray() (which can be found out by reflection), the root AbstractCollection.toArray() is not behaving fine there.

For harmony the fix would be to correct this issue "correctly" by changing the base AbstractCollection implementation (I would recommend that).

This is also the root cause for HARMONY-6236 and similar issues, the fix there is invalid, but I cannot reopen the issue.

  was:
If you call ConcurrentHashMap.keySet().toArray() [as done in trunks Lucene's RAMDirectory#fileMap] and another thread modifies the collecton, you get NoSuchElementExceptions or AIOOBEs. The reason is that AbstractCollection.toArray methods allocate the array using the current size of the collection and then either iterate on the values (which is oficially supported by ConcurrentHashMap, its iterator is safe for concurrent modification!) and set them on the target without checking bounds. On the other hand if there are too few entries in the collection, the array is nulled at the end. The bad thing is that the toArray() and toArray(T[]) methods behave differently, so depending on the modification they throw different exceptions (one impl simply drops entries that dont fit into the array).

Since Java SE 6, its officially documented, how toArray must behave: [http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray(T[])]; This is violated by harmony and even the fix in HARMONY-6419 does not respect it, leading to such bugs.

Java SE 5 does not document that, but ConcurrentHashMap.keySet(), values() and entrySet() have own implementations of toArray() (which can be found out by reflection), the root AbstractCollection.toArray() is not behaving fine there.

For harmony the fix would be to correct this issue "correctly" by changing the base AbstractCollection implementation (I would recommend that).

This is also the root cause for HARMONY-6419 and similar issues, the fix there is invalid, but I cannot reopen the issue.


> AbstractCollection.toArray() and AbstractCollection.toArray(T[]) are broken for concurrently modified collections like ConcurrentHashMap.keySet()
> -------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HARMONY-6681
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6681
>             Project: Harmony
>          Issue Type: Bug
>          Components: Classlib
>    Affects Versions: 6.0M4, 5.0M16
>            Reporter: Uwe Schindler
>
> If you call ConcurrentHashMap.keySet().toArray() [as done in trunks Lucene's RAMDirectory#fileMap] and another thread modifies the collecton, you get NoSuchElementExceptions or AIOOBEs. The reason is that AbstractCollection.toArray methods allocate the array using the current size of the collection and then either iterate on the values (which is oficially supported by ConcurrentHashMap, its iterator is safe for concurrent modification!) and set them on the target without checking bounds. On the other hand if there are too few entries in the collection, the array is nulled at the end. The bad thing is that the toArray() and toArray(T[]) methods behave differently, so depending on the modification they throw different exceptions (one impl simply drops entries that dont fit into the array).
> Since Java SE 6, its officially documented, how toArray must behave: [http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray(T[])]; This is violated by harmony and even the fix in HARMONY-6236 does not respect it, leading to such bugs.
> Java SE 5 does not document that, but ConcurrentHashMap.keySet(), values() and entrySet() have own implementations of toArray() (which can be found out by reflection), the root AbstractCollection.toArray() is not behaving fine there.
> For harmony the fix would be to correct this issue "correctly" by changing the base AbstractCollection implementation (I would recommend that).
> This is also the root cause for HARMONY-6236 and similar issues, the fix there is invalid, but I cannot reopen the issue.

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


Re: [jira] Updated: (HARMONY-6681) AbstractCollection.toArray() and AbstractCollection.toArray(T[]) are broken for concurrently modified collections like ConcurrentHashMap.keySet()

Posted by Prashanth K S <pr...@gmail.com>.
JIRA 6678 attempts to address the same. A patch has been attached to the
JIRA and is yet to be committed. Kindly test the behavior after the fix has
been committed.

-- 
Regards
Prashanth


On Tue, Nov 30, 2010 at 10:18 PM, Uwe Schindler (JIRA) <ji...@apache.org>wrote:

>
>     [
> https://issues.apache.org/jira/browse/HARMONY-6681?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel]
>
> Uwe Schindler updated HARMONY-6681:
> -----------------------------------
>
>    Description:
> If you call ConcurrentHashMap.keySet().toArray() [as done in trunks
> Lucene's RAMDirectory#fileMap] and another thread modifies the collecton,
> you get NoSuchElementExceptions or AIOOBEs. The reason is that
> AbstractCollection.toArray methods allocate the array using the current size
> of the collection and then either iterate on the values (which is oficially
> supported by ConcurrentHashMap, its iterator is safe for concurrent
> modification!) and set them on the target without checking bounds. On the
> other hand if there are too few entries in the collection, the array is
> nulled at the end. The bad thing is that the toArray() and toArray(T[])
> methods behave differently, so depending on the modification they throw
> different exceptions (one impl simply drops entries that dont fit into the
> array).
>
> Since Java SE 6, its officially documented, how toArray must behave: [
> http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray(T[])<http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray%28T[]%29>];
> This is violated by harmony and even the fix in HARMONY-6236 does not
> respect it, leading to such bugs.
>
> Java SE 5 does not document that, but ConcurrentHashMap.keySet(), values()
> and entrySet() have own implementations of toArray() (which can be found out
> by reflection), the root AbstractCollection.toArray() is not behaving fine
> there.
>
> For harmony the fix would be to correct this issue "correctly" by changing
> the base AbstractCollection implementation (I would recommend that).
>
> This is also the root cause for HARMONY-6236 and similar issues, the fix
> there is invalid, but I cannot reopen the issue.
>
>  was:
> If you call ConcurrentHashMap.keySet().toArray() [as done in trunks
> Lucene's RAMDirectory#fileMap] and another thread modifies the collecton,
> you get NoSuchElementExceptions or AIOOBEs. The reason is that
> AbstractCollection.toArray methods allocate the array using the current size
> of the collection and then either iterate on the values (which is oficially
> supported by ConcurrentHashMap, its iterator is safe for concurrent
> modification!) and set them on the target without checking bounds. On the
> other hand if there are too few entries in the collection, the array is
> nulled at the end. The bad thing is that the toArray() and toArray(T[])
> methods behave differently, so depending on the modification they throw
> different exceptions (one impl simply drops entries that dont fit into the
> array).
>
> Since Java SE 6, its officially documented, how toArray must behave: [
> http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray(T[])<http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray%28T[]%29>];
> This is violated by harmony and even the fix in HARMONY-6419 does not
> respect it, leading to such bugs.
>
> Java SE 5 does not document that, but ConcurrentHashMap.keySet(), values()
> and entrySet() have own implementations of toArray() (which can be found out
> by reflection), the root AbstractCollection.toArray() is not behaving fine
> there.
>
> For harmony the fix would be to correct this issue "correctly" by changing
> the base AbstractCollection implementation (I would recommend that).
>
> This is also the root cause for HARMONY-6419 and similar issues, the fix
> there is invalid, but I cannot reopen the issue.
>
>
> > AbstractCollection.toArray() and AbstractCollection.toArray(T[]) are
> broken for concurrently modified collections like ConcurrentHashMap.keySet()
> >
> -------------------------------------------------------------------------------------------------------------------------------------------------
> >
> >                 Key: HARMONY-6681
> >                 URL: https://issues.apache.org/jira/browse/HARMONY-6681
> >             Project: Harmony
> >          Issue Type: Bug
> >          Components: Classlib
> >    Affects Versions: 6.0M4, 5.0M16
> >            Reporter: Uwe Schindler
> >
> > If you call ConcurrentHashMap.keySet().toArray() [as done in trunks
> Lucene's RAMDirectory#fileMap] and another thread modifies the collecton,
> you get NoSuchElementExceptions or AIOOBEs. The reason is that
> AbstractCollection.toArray methods allocate the array using the current size
> of the collection and then either iterate on the values (which is oficially
> supported by ConcurrentHashMap, its iterator is safe for concurrent
> modification!) and set them on the target without checking bounds. On the
> other hand if there are too few entries in the collection, the array is
> nulled at the end. The bad thing is that the toArray() and toArray(T[])
> methods behave differently, so depending on the modification they throw
> different exceptions (one impl simply drops entries that dont fit into the
> array).
> > Since Java SE 6, its officially documented, how toArray must behave: [
> http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray(T[])<http://download.oracle.com/javase/6/docs/api/java/util/AbstractCollection.html#toArray%28T[]%29>];
> This is violated by harmony and even the fix in HARMONY-6236 does not
> respect it, leading to such bugs.
> > Java SE 5 does not document that, but ConcurrentHashMap.keySet(),
> values() and entrySet() have own implementations of toArray() (which can be
> found out by reflection), the root AbstractCollection.toArray() is not
> behaving fine there.
> > For harmony the fix would be to correct this issue "correctly" by
> changing the base AbstractCollection implementation (I would recommend
> that).
> > This is also the root cause for HARMONY-6236 and similar issues, the fix
> there is invalid, but I cannot reopen the issue.
>
> --
> This message is automatically generated by JIRA.
> -
> You can reply to this email to add a comment to the issue online.
>
>