IndexOutOfBoundsException in ThreadProxyEventList.applyChangeToCache

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

IndexOutOfBoundsException in ThreadProxyEventList.applyChangeToCache

Michael Heuer
Hello,

I am seeing something new with version 1.9.0 that I don't remember seeing before

Exception in thread "AWT-EventQueue-0"
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.rangeCheck(ArrayList.java:635)
        at java.util.ArrayList.get(ArrayList.java:411)
        at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.applyChangeToCache(ThreadProxyEventList.java:179)
        at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.access$600(ThreadProxyEventList.java:68)
        at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.listChanged(ThreadProxyEventList.java:242)
        at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:424)
        at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:421)
        at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:445)
        at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:344)
        at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:317)
        at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.run(ThreadProxyEventList.java:230)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:688)
        at java.awt.EventQueue$3.run(EventQueue.java:686)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)


This is happening on a call to eventList.add(foo).

I have a label listening to the eventList and it properly shows the
size of the eventList, but I also have a table listening to the
eventList, and it shows nothing, as if no elements have been added.

I am still using some classes and methods that have been deprecated,
if that matters.

   michael
Reply | Threaded
Open this post in threaded view
|

Re: IndexOutOfBoundsException in ThreadProxyEventList.applyChangeToCache

Michael Heuer
My apologies, I see the same with version 1.8.0, I must have something
wrong with my locking.

   michael


On Tue, Aug 13, 2013 at 1:01 PM, Michael Heuer <[hidden email]> wrote:

> Hello,
>
> I am seeing something new with version 1.9.0 that I don't remember seeing before
>
> Exception in thread "AWT-EventQueue-0"
> java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
>         at java.util.ArrayList.rangeCheck(ArrayList.java:635)
>         at java.util.ArrayList.get(ArrayList.java:411)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.applyChangeToCache(ThreadProxyEventList.java:179)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.access$600(ThreadProxyEventList.java:68)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.listChanged(ThreadProxyEventList.java:242)
>         at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:424)
>         at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:421)
>         at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:445)
>         at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:344)
>         at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:317)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.run(ThreadProxyEventList.java:230)
>         at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
>         at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
>         at java.awt.EventQueue.access$200(EventQueue.java:103)
>         at java.awt.EventQueue$3.run(EventQueue.java:688)
>         at java.awt.EventQueue$3.run(EventQueue.java:686)
>         at java.security.AccessController.doPrivileged(Native Method)
>         at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
>         at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
>         at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
>         at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
>         at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
>         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
>         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
>         at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
>
>
> This is happening on a call to eventList.add(foo).
>
> I have a label listening to the eventList and it properly shows the
> size of the eventList, but I also have a table listening to the
> eventList, and it shows nothing, as if no elements have been added.
>
> I am still using some classes and methods that have been deprecated,
> if that matters.
>
>    michael
Reply | Threaded
Open this post in threaded view
|

Re: IndexOutOfBoundsException in ThreadProxyEventList.applyChangeToCache

James Lemieux
Hey Michael,

   Only you truly know your application requirements, so take this advice with a grain of salt and do what you think is right. Everyone else reading this thread at some point later, take this as a general guideline:

   So, the GL ThreadProxying EventList is nice for removing some Threading concerns re: the EDT, but it comes at a price, which you have encountered. Updates on background Threads and reads on the EDT have to be perfectly locked or you have the potential for data structures on each side of the ThreadProxy being slightly out of date for brief periods of time.

   Where possible, I prefer to remove this locking burden by accessing the pipeline on a single Thread (the EDT). This is both conceptually simple and always 100% correct behavior provided you follow the rule (i.e. all reads are writes are will be 100% correct). In fact, this is one of the reasons that DefaultEventTableModel and its cousins no longer *automatically* decorate the source EventList with a SwingThreadProxyEventList. Why pay the price of ThreadProxying if you only use one Thread?

   So, when should you use a ThreadProxy and take on the burden of locking? Answer: when your data is so voluminous and your transformations so expensive that doing them on the EDT would cause noticeable GUI pauses. Each application is very unique in these regards, so it is left to the developer to "pick their poison" between single-threaded access and multi-threaded with locking.

   If you're having trouble tracking down the code that might be missing some locking, you can temporarily swap a DebugList in place of your BasicEventList and turn on lock checking. It will provide you with a call stack showing you where unguarded access came from.

Good Luck Michael!

James


On Tue, Aug 13, 2013 at 11:15 AM, Michael Heuer <[hidden email]> wrote:
My apologies, I see the same with version 1.8.0, I must have something
wrong with my locking.

   michael


On Tue, Aug 13, 2013 at 1:01 PM, Michael Heuer <[hidden email]> wrote:
> Hello,
>
> I am seeing something new with version 1.9.0 that I don't remember seeing before
>
> Exception in thread "AWT-EventQueue-0"
> java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
>         at java.util.ArrayList.rangeCheck(ArrayList.java:635)
>         at java.util.ArrayList.get(ArrayList.java:411)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.applyChangeToCache(ThreadProxyEventList.java:179)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.access$600(ThreadProxyEventList.java:68)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.listChanged(ThreadProxyEventList.java:242)
>         at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:424)
>         at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:421)
>         at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:445)
>         at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:344)
>         at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:317)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.run(ThreadProxyEventList.java:230)
>         at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
>         at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
>         at java.awt.EventQueue.access$200(EventQueue.java:103)
>         at java.awt.EventQueue$3.run(EventQueue.java:688)
>         at java.awt.EventQueue$3.run(EventQueue.java:686)
>         at java.security.AccessController.doPrivileged(Native Method)
>         at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
>         at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
>         at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
>         at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
>         at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
>         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
>         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
>         at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
>
>
> This is happening on a call to eventList.add(foo).
>
> I have a label listening to the eventList and it properly shows the
> size of the eventList, but I also have a table listening to the
> eventList, and it shows nothing, as if no elements have been added.
>
> I am still using some classes and methods that have been deprecated,
> if that matters.
>
>    michael

Reply | Threaded
Open this post in threaded view
|

Re: IndexOutOfBoundsException in ThreadProxyEventList.applyChangeToCache

robeden
I whole-heartedly agree with James. In my experience, keeping to a single thread on the pipeline is the way to go.

Rob

On Aug 13, 2013, at 1:40 PM, James Lemieux <[hidden email]> wrote:

Hey Michael,

   Only you truly know your application requirements, so take this advice with a grain of salt and do what you think is right. Everyone else reading this thread at some point later, take this as a general guideline:

   So, the GL ThreadProxying EventList is nice for removing some Threading concerns re: the EDT, but it comes at a price, which you have encountered. Updates on background Threads and reads on the EDT have to be perfectly locked or you have the potential for data structures on each side of the ThreadProxy being slightly out of date for brief periods of time.

   Where possible, I prefer to remove this locking burden by accessing the pipeline on a single Thread (the EDT). This is both conceptually simple and always 100% correct behavior provided you follow the rule (i.e. all reads are writes are will be 100% correct). In fact, this is one of the reasons that DefaultEventTableModel and its cousins no longer *automatically* decorate the source EventList with a SwingThreadProxyEventList. Why pay the price of ThreadProxying if you only use one Thread?

   So, when should you use a ThreadProxy and take on the burden of locking? Answer: when your data is so voluminous and your transformations so expensive that doing them on the EDT would cause noticeable GUI pauses. Each application is very unique in these regards, so it is left to the developer to "pick their poison" between single-threaded access and multi-threaded with locking.

   If you're having trouble tracking down the code that might be missing some locking, you can temporarily swap a DebugList in place of your BasicEventList and turn on lock checking. It will provide you with a call stack showing you where unguarded access came from.

Good Luck Michael!

James


On Tue, Aug 13, 2013 at 11:15 AM, Michael Heuer <[hidden email]> wrote:
My apologies, I see the same with version 1.8.0, I must have something
wrong with my locking.

   michael


On Tue, Aug 13, 2013 at 1:01 PM, Michael Heuer <[hidden email]> wrote:
> Hello,
>
> I am seeing something new with version 1.9.0 that I don't remember seeing before
>
> Exception in thread "AWT-EventQueue-0"
> java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
>         at java.util.ArrayList.rangeCheck(ArrayList.java:635)
>         at java.util.ArrayList.get(ArrayList.java:411)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.applyChangeToCache(ThreadProxyEventList.java:179)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.access$600(ThreadProxyEventList.java:68)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.listChanged(ThreadProxyEventList.java:242)
>         at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:424)
>         at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:421)
>         at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:445)
>         at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:344)
>         at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:317)
>         at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.run(ThreadProxyEventList.java:230)
>         at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
>         at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
>         at java.awt.EventQueue.access$200(EventQueue.java:103)
>         at java.awt.EventQueue$3.run(EventQueue.java:688)
>         at java.awt.EventQueue$3.run(EventQueue.java:686)
>         at java.security.AccessController.doPrivileged(Native Method)
>         at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
>         at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
>         at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
>         at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
>         at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
>         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
>         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
>         at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
>
>
> This is happening on a call to eventList.add(foo).
>
> I have a label listening to the eventList and it properly shows the
> size of the eventList, but I also have a table listening to the
> eventList, and it shows nothing, as if no elements have been added.
>
> I am still using some classes and methods that have been deprecated,
> if that matters.
>
>    michael


Reply | Threaded
Open this post in threaded view
|

Re: IndexOutOfBoundsException in ThreadProxyEventList.applyChangeToCache

Michael Heuer
Thank you for the replies, Rob and James.

In this particular case, I depend on the threading facilities provided
by the host app Cytoscape3

http://cytoscape.org/

My error below was in fact caused by a write from a
Cytoscape3-provided worker thread that was missing its write lock.

Thanks again,

   michael


On Tue, Aug 13, 2013 at 1:55 PM, Rob Eden <[hidden email]> wrote:

> I whole-heartedly agree with James. In my experience, keeping to a single
> thread on the pipeline is the way to go.
>
> Rob
>
> On Aug 13, 2013, at 1:40 PM, James Lemieux <[hidden email]> wrote:
>
> Hey Michael,
>
>    Only you truly know your application requirements, so take this advice
> with a grain of salt and do what you think is right. Everyone else reading
> this thread at some point later, take this as a general guideline:
>
>    So, the GL ThreadProxying EventList is nice for removing some Threading
> concerns re: the EDT, but it comes at a price, which you have encountered.
> Updates on background Threads and reads on the EDT have to be perfectly
> locked or you have the potential for data structures on each side of the
> ThreadProxy being slightly out of date for brief periods of time.
>
>    Where possible, I prefer to remove this locking burden by accessing the
> pipeline on a single Thread (the EDT). This is both conceptually simple and
> always 100% correct behavior provided you follow the rule (i.e. all reads
> are writes are will be 100% correct). In fact, this is one of the reasons
> that DefaultEventTableModel and its cousins no longer *automatically*
> decorate the source EventList with a SwingThreadProxyEventList. Why pay the
> price of ThreadProxying if you only use one Thread?
>
>    So, when should you use a ThreadProxy and take on the burden of locking?
> Answer: when your data is so voluminous and your transformations so
> expensive that doing them on the EDT would cause noticeable GUI pauses. Each
> application is very unique in these regards, so it is left to the developer
> to "pick their poison" between single-threaded access and multi-threaded
> with locking.
>
>    If you're having trouble tracking down the code that might be missing
> some locking, you can temporarily swap a DebugList in place of your
> BasicEventList and turn on lock checking. It will provide you with a call
> stack showing you where unguarded access came from.
>
> Good Luck Michael!
>
> James
>
>
> On Tue, Aug 13, 2013 at 11:15 AM, Michael Heuer <[hidden email]> wrote:
>>
>> My apologies, I see the same with version 1.8.0, I must have something
>> wrong with my locking.
>>
>>    michael
>>
>>
>> On Tue, Aug 13, 2013 at 1:01 PM, Michael Heuer <[hidden email]> wrote:
>> > Hello,
>> >
>> > I am seeing something new with version 1.9.0 that I don't remember
>> > seeing before
>> >
>> > Exception in thread "AWT-EventQueue-0"
>> > java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
>> >         at java.util.ArrayList.rangeCheck(ArrayList.java:635)
>> >         at java.util.ArrayList.get(ArrayList.java:411)
>> >         at
>> > ca.odell.glazedlists.impl.gui.ThreadProxyEventList.applyChangeToCache(ThreadProxyEventList.java:179)
>> >         at
>> > ca.odell.glazedlists.impl.gui.ThreadProxyEventList.access$600(ThreadProxyEventList.java:68)
>> >         at
>> > ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.listChanged(ThreadProxyEventList.java:242)
>> >         at
>> > ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:424)
>> >         at
>> > ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:421)
>> >         at
>> > ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:445)
>> >         at
>> > ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:344)
>> >         at
>> > ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:317)
>> >         at
>> > ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.run(ThreadProxyEventList.java:230)
>> >         at
>> > java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
>> >         at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
>> >         at java.awt.EventQueue.access$200(EventQueue.java:103)
>> >         at java.awt.EventQueue$3.run(EventQueue.java:688)
>> >         at java.awt.EventQueue$3.run(EventQueue.java:686)
>> >         at java.security.AccessController.doPrivileged(Native Method)
>> >         at
>> > java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
>> >         at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
>> >         at
>> > java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
>> >         at
>> > java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
>> >         at
>> > java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
>> >         at
>> > java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
>> >         at
>> > java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
>> >         at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
>> >
>> >
>> > This is happening on a call to eventList.add(foo).
>> >
>> > I have a label listening to the eventList and it properly shows the
>> > size of the eventList, but I also have a table listening to the
>> > eventList, and it shows nothing, as if no elements have been added.
>> >
>> > I am still using some classes and methods that have been deprecated,
>> > if that matters.
>> >
>> >    michael