Uploaded image for project: 'Commons Lang'
  1. Commons Lang
  2. LANG-762

Handle or document ReflectionToStringBuilder and ToStringBuilder for collections that are not thread safe

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Won't Fix
    • None
    • 3.2
    • lang.builder.*
    • None

    Description

      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.

      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)
      

      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:

          @Override
          public synchronized String toString() {
              return ReflectionToStringBuilder.toString(this);
          }
      
      • Or have our code in ReflectionToStringBuilder and ToStringBuilder lock collections while they are being toString'd.

      Attachments

        1. patch-LANG762.txt
          0.9 kB
          Adrian Cumiskey
        2. ReflectionToStringBuilderConcurrencyTest.java
          3 kB
          Phil Steitz

        Activity

          People

            Unassigned Unassigned
            ggregory Gary D. Gregory
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: