I'm in over my head again. But at least the "good" news is that I think I'm finally inching my way toward the deep end of the pool...
We're suddenly running into the WOBrowser "java.lang.UnsupportedOperationException: addAll is not a supported operation in com.webobjects.foundation.NSArray" problem as others have run into.
We have a WOComponent that has three WOBrowsers on it. One selects one or more "Categories" from all possibilities. The other two manage what related objects are related to the selected Categories. One with Available Objects, and one with Assigned Objects. Basically, with 3 WOBrowsers we are managing a Many-to-Many relationship.
Now, we can easily avoid the error by just making sure that the "selections" bindings of the WOBrowsers are not null. Initializing them with NSArray.emptyArray() works just fine.
There are two odd things:
1) We just started running into this problem and this code has been running unchanged for years, and Wonder's last change was 16+ months ago
2) There are three WOBrowsers on the Page (2 in one component, 1 in a parent component) and only ONE of the WOBrowsers is causing this error.
I believe there is a bug in WO's or WOnder's handling of WOBrowser, but maybe (probably) I'm just not fully understanding the implications of multiple WOBrowsers in one Page and the Request-Response loop.
526 if(_selections != null && _selections.isValueSettable()) {
526 try {
527 Class resultClass = listClassInContext(context);
528 Object result = resultClass.newInstance();
529 if(result instanceof NSMutableArray) {
530 ((NSMutableArray)result).addObjects(selections.toArray());
531 } else {
532 if(result instanceof List) {
533 ((List)result).addAll(selections);
534 }
535 }
536
_selections.setValue(result, context.component());
537 } catch(Exception exception) {
If I add the following two lines:
531 + } else if (result instanceof NSArray) {
532 + result = new NSArray(selections.toArray());
Or surround lines 529 - 535 with the following if clause:
529 + if (selections != null && !selections.isEmpty()) {...
537 + }
Then everything works just fine, even if the selections bindings end up null.
That's all very special, but it just covers up the real problem by intercepting the bad data before it can cause an error. They don't fix what is causing the bad data in the first place.
It appears that for some reason line 527's call to EOAssociation#listClassInContext(context) for just ONE of the three WOBrowsers returns an instance of NSArray instead of an NSMutableArray. The one that gets an NSArray Class is the third WOBrowser on the page, but possibly more significantly it's the second with a null "selections" binding.
What I don't get is why would EOAssociation#listClassInContext(context) return different Class objects (NSMutableArray for the first, NSArray for the second) even when both WOBrowser "selections" bindings are null?
Does anybody have any ideas?
(Clarification for Chuck: I mean ideas that don't directly or indirectly involve bourbon and/or hookers)
Dave