Bug 560206 - IndexOutOfBounds Exception in ContentBehavior
Summary: IndexOutOfBounds Exception in ContentBehavior
Status: NEW
Alias: None
Product: GEF
Classification: Tools
Component: GEF MVC (show other bugs)
Version: 5.2.0   Edit
Hardware: PC Linux
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: gef-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-02-16 20:03 EST by Kyle Girard CLA
Modified: 2020-03-10 09:17 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kyle Girard CLA 2020-02-16 20:03:32 EST
I upgraded our RCP to Java 11 and Eclipse 2019-12 from Java 8 and Eclipse Oxygen.  Surprisingly every seems to work.  However, When I add nodes to my graph in a certain order I get a index out of bounds exception (on both linux and windows) in ContentBehavior: (here's the relevant parts):

java.lang.IndexOutOfBoundsException: Index: 16, Size: 11
	at java.base/java.util.ArrayList.rangeCheckForAdd(ArrayList.java:787)
	at java.base/java.util.ArrayList.addAll(ArrayList.java:731)
	at com.google.common.collect.ForwardingList.addAll(ForwardingList.java:75)
	at org.eclipse.gef.common.collections.ObservableListWrapperEx.addAll(ObservableListWrapperEx.java:122)
	at org.eclipse.gef.mvc.fx.parts.AbstractVisualPart.addChildren(AbstractVisualPart.java:200)
	at org.eclipse.gef.mvc.fx.behaviors.ContentBehavior.lambda$1(ContentBehavior.java:501)
	at com.google.common.collect.Maps$KeySet.lambda$forEach$0(Maps.java:3822)
	at java.base/java.util.HashMap.forEach(HashMap.java:1336)
	at com.google.common.collect.Maps$KeySet.forEach(Maps.java:3822)
	at org.eclipse.gef.mvc.fx.behaviors.ContentBehavior.synchronizeContentPartChildren(ContentBehavior.java:498)
	at org.eclipse.gef.mvc.fx.behaviors.ContentBehavior$2.onChanged(ContentBehavior.java:123)
	at org.eclipse.gef.common.collections.ListListenerHelperEx.notifyListChangeListeners(ListListenerHelperEx.java:650)
	at org.eclipse.gef.common.beans.binding.ListExpressionHelperEx.fireValueChangedEvent(ListExpressionHelperEx.java:109)
	at org.eclipse.gef.common.beans.property.ReadOnlyListWrapperEx$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyListWrapperEx.java:91)
	at org.eclipse.gef.common.beans.property.ReadOnlyListWrapperEx$ReadOnlyPropertyImpl.access$2(ReadOnlyListWrapperEx.java:87)
	at org.eclipse.gef.common.beans.property.ReadOnlyListWrapperEx.fireValueChangedEvent(ReadOnlyListWrapperEx.java:234)
	at javafx.base/javafx.beans.property.ListPropertyBase.lambda$new$0(ListPropertyBase.java:57)
	at javafx.base/com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
	at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
	at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
	at javafx.base/javafx.collections.FXCollections$UnmodifiableObservableListImpl.lambda$new$0(FXCollections.java:955)
	at javafx.base/javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
	at org.eclipse.gef.common.collections.ListListenerHelperEx.notifyListChangeListeners(ListListenerHelperEx.java:650)
	at org.eclipse.gef.common.collections.ListListenerHelperEx.fireValueChangedEvent(ListListenerHelperEx.java:600)
	at org.eclipse.gef.common.collections.ObservableListWrapperEx.setAll(ObservableListWrapperEx.java:355)
	at org.eclipse.gef.mvc.fx.parts.AbstractContentPart.addContentChild(AbstractContentPart.java:132)
	at org.eclipse.gef.mvc.fx.operations.AddContentChildOperation.execute(AddContentChildOperation.java:78)
	at org.eclipse.gef.mvc.fx.operations.AbstractCompositeOperation.execute(AbstractCompositeOperation.java:142)
	at org.eclipse.gef.mvc.fx.policies.AbstractPolicy.locallyExecuteOperation(AbstractPolicy.java:143)
	at org.eclipse.gef.mvc.fx.policies.ContentPolicy.addContentChild(ContentPolicy.java:71)
	at org.eclipse.gef.mvc.fx.policies.CreationPolicy.create(CreationPolicy.java:118)
	at org.eclipse.gef.mvc.fx.policies.CreationPolicy.create(CreationPolicy.java:200)


I investigated and it appears that since childContentsParts.keySet() can return integers in any order.  If it returns the index of next element added everything works.  If it returns anything else the above exception is thrown.  To test this...I created my own copy ContentBehavior class where I convert the keySet to an array and sort it and leave everything else unchanged and I don't get the exception anymore.  

Replace:

childContentParts.keySet().foreach(cp -> { ....

with 

ArrayList<Integer> keys = new ArrayList<>(childContentParts.keySet());
Collections.sort(keys);
keys.forEach(cp -> { .....


Don't have time to investigate it further to see if this is a proper fix but it works for me.
Comment 1 Matthias Wienand CLA 2020-03-10 09:17:27 EDT
That does look like an important finding. I will investigate and create a regression test. Thank you for reporting!