You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Adrian Cumiskey (Updated) (JIRA)" <ji...@apache.org> on 2011/10/22 04:00:32 UTC

[jira] [Updated] (LANG-762) Handle or document ReflectionToStringBuilder and ToStringBuilder for collections that are not thread safe

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

Adrian Cumiskey updated LANG-762:
---------------------------------

    Attachment: patch-LANG762.txt

I tried pretty hard to try and reproduce ConcurrentModificationException in a fairly elaborate multithreaded unit test (but alas failed...).

I looked at the two approaches you proposed for fixing this issue.  I believe it is not correct to expect the ReflectionToStringBuilder caller to synchronize his toString() implementation.  

I believe the best place for the guard is just prior to the object being appended by the StringBuffer.  I have provided a small patch that takes care of synchronizing any Collection or Map in ToStringStyle. 

Cheers, Adrian.
                
> Handle or document ReflectionToStringBuilder and ToStringBuilder for collections that are not thread safe
> ---------------------------------------------------------------------------------------------------------
>
>                 Key: LANG-762
>                 URL: https://issues.apache.org/jira/browse/LANG-762
>             Project: Commons Lang
>          Issue Type: Bug
>          Components: lang.builder.*
>         Environment: Apache Maven 3.0.3 (r1075438; 2011-02-28 12:31:09-0500)
> Maven home: C:\Java\apache-maven-3.0.3\bin\..
> Java version: 1.6.0_24, vendor: Sun Microsystems Inc.
> Java home: C:\Program Files\Java\jdk1.6.0_24\jre
> Default locale: en_US, platform encoding: Cp1252
> OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
>            Reporter: Gary D. Gregory
>         Attachments: patch-LANG762.txt
>
>
> Moving discussion here from https://issues.apache.org/jira/browse/POOL-191 ConcurrentModificationException in GenericObjectPool LinkedList.
> It is possible to get a {{ConcurrentModificationException}} in a {{LinkedList}} from a Commons Pool {{GenericObjectPool}}.
> This happens when I call {{ReflectionToStringBuilder.toString(this)}} from a subclass of {{GenericObjectPool}}. My guess is that it would happen with just {{ReflectionToStringBuilder.toString(gop)}}. IOW, subclassing does not have anything to do with it I would venture.
> For example, in this stack trace {{JmsSessionPool}} is a subclass of {{GenericObjectPool}}.
> {noformat}
> java.util.ConcurrentModificationException
> at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
> at java.util.LinkedList$ListItr.next(LinkedList.java:696)
> at java.util.AbstractCollection.toString(AbstractCollection.java:421)
> at java.lang.String.valueOf(String.java:2826)
> at java.lang.StringBuffer.append(StringBuffer.java:219)
> at org.apache.commons.lang3.builder.ToStringStyle.appendDetail(ToStringStyle.java:598)
> at org.apache.commons.lang3.builder.ToStringStyle.appendInternal(ToStringStyle.java:473)
> at org.apache.commons.lang3.builder.ToStringStyle.append(ToStringStyle.java:436)
> at org.apache.commons.lang3.builder.ToStringBuilder.append(ToStringBuilder.java:848)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:528)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:692)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:288)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:119)
> at com.seagullsw.appinterface.comm.jms.JmsSessionPool.toString(JmsSessionPool.java:120)
> at java.lang.String.valueOf(String.java:2826)
> at java.lang.StringBuffer.append(StringBuffer.java:219)
> at org.apache.commons.lang3.builder.ToStringStyle.appendDetail(ToStringStyle.java:586)
> at org.apache.commons.lang3.builder.ToStringStyle.appendInternal(ToStringStyle.java:550)
> at org.apache.commons.lang3.builder.ToStringStyle.append(ToStringStyle.java:436)
> at org.apache.commons.lang3.builder.ToStringBuilder.append(ToStringBuilder.java:848)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:528)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:689)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:288)
> at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:119)
> at com.seagullsw.appinterface.server.comm.BasicCommunicationManager.toString(BasicCommunicationManager.java:828)
> at com.seagullsw.appinterface.server.comm.BasicCommunicationManager.toString(BasicCommunicationManager.java:817)
> at java.lang.String.valueOf(String.java:2826)
> at java.lang.StringBuilder.append(StringBuilder.java:115)
> at com.seagullsw.appinterface.server.AisHelper.waitForCommuncationManagers(AisHelper.java:217)
> at com.seagullsw.appinterface.server.AisHelper.start(AisHelper.java:136)
> at com.seagullsw.appinterface.server.AisHelper.startFromResource(AisHelper.java:161)
> at com.seagullsw.appinterface.server.AbstractServerJunit4.startServer(AbstractServerJunit4.java:179)
> at com.seagullsw.appinterface.server.comm.jms.AbstractJmsRoundtripMaxConcurrencyTestCase.setUpOnce(AbstractJmsRoundtripMaxConcurrencyTestCase.java:141)
> at com.seagullsw.appinterface.server.comm.jms.ibmmq.JmsRoundtripMaxConcurrency032TestCase.setUpOnce(JmsRoundtripMaxConcurrency032TestCase.java:40)
> {noformat}
> We should either: 
> - Document ReflectionToStringBuilder and ToStringBuilder such that call sites use synchronized if the object passed in contains collections that are not thread-safe. F
> or example:
> {code:java}
>     @Override
>     public synchronized String toString() {
>         return ReflectionToStringBuilder.toString(this);
>     }
> {code}
> - Or have our code in ReflectionToStringBuilder and ToStringBuilder lock collections while they are being toString'd.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira