Description
When removing a component's MetaData entry from within a Behavior's detach(Component component) method, Wicket can run into issues due to a loop index being out of sync with the array it is iterating over.
The attached quickstart shows the problem in the log when the HomePage is opened.
Explanation:
The included VisibilityBehavior class adds a MetaData entry to the component it is attached to. Upon detaching the Behavior this MetaData entry is set to null again. Setting a MetaData entry to null removes it from the component's data array, moving all elements following it further up in the array.
State captured in org.apache.wicket.Behaviors.detach(Component):
Right before detaching the Behavior:
Loop index "i" = 2
Content of the component's "data" array:
- [0] the component's Model
- [1] the MetaDataEntry belonging to the described Behavior
- [2] the Behavior itself
- [3] an AttributeModifier with a StringResourceModel
Start of next iteration after the Behavior was detached
Loop index "i" = 3
Content of the component's "data" array:
- [0] the component's Model
- [1] the Behavior itself
- [2] an AttributeModifier with a StringResourceModel
Result:
The AttributeModifier is skipped and doesn't get detached, resulting in the NotDetachedModelChecker reporting a not detached model in the AttributeModifier, when the HomePage gets opened.
This might be fixable with the suggested separation of Models, Behaviors and MetaData from WICKET-6774. Alternatively Wicket could maybe raise an exception or log a warning if the size of the data field changed during detaching.
The problem was first discovered in 8.10.0 and reproduced with 9.3.0 in the quickstart.