History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: XFIRE-586
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Dan Diephouse
Reporter: Andrzej Doyle
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
XFire

Type gets registered with two different type mappings, orphaning the first one

Created: 16/Aug/06 10:31 AM   Updated: 15/Sep/06 01:46 PM
Component/s: Core
Affects Version/s: 1.2-RC
Fix Version/s: 1.2.2

Time Tracking:
Not Specified


 Description  « Hide
When trying to implement type overriding in a webapp, I noticed that despite xsi:type attributes being sent over correctly, the server wouldn't deserialise into the correct concrete implementations of the declared interface. Upon further examination, it seems that in AegisBindingProvider.getReadType() line 160, the TypeMapping returned by type.getTypeMapping() can't find the overriding class. The TypeMapping that corresponds to my service does have the overriding classes defined in it. Somewhere along the way the two got confused.

The actual object I'm trying to deserialise is a bean that contains a List of the interface I want to override. AegisBindingParameter.readParameter() gets the correct TypeMapping for my Service, which is then used to find the CollectionType for my interface (all well and good so far), and then that type's TypeMapping (also the same one) is used to find the BeanType for my interface. Then getReadType() uses the BeanType's TypeMapping to find the overriding type. But lo and behold, the TypeMapping returned by getTypeMapping() on my interface's BeanType is NOT the same TypeMapping defined by my Service and used by all the other types - and so it can't find the overriding types.

Amazed at this, I set a conditional breakpoint on CustomTypeMapping.register(), and found that it's seemingly not uncommon for a type that already has an associated TypeMapping to be registered with another TypeMapping, thus losing the link back to its previous mapping. This leads to a situation where for a TypeMapping tm, tm.getType(foo).getTypeMapping() != tm. My reading of the code is that this condition is assumed to always hold.

So either:
i) That assumption's correct, and a Type should only ever be registered with one TypeMapping. In which case the problem code is around BeanTypeInfo.getType(), which (in the 3rd case) creates a Type that is already registered with another TypeMapping other than the tm variable in that method. The root cause of this is that tm.getTypeCreator().getTypeMapping() != tm, so we've got yet another level of multiple registration. Where this happens I'm not so sure - though in DefaultTypeMappingRegistry.createTypeMapping() we get an instance where a TypeCreator that is registered with one TypeMapping is then registered with another.
ii) The assumption is wrong and Types are allowed to be registered with multiple TypeMappings. Then the AegisBindingProvider makes this assumption too, and as a result it can't find overriding types properly. I'm not sure what the solution would be here - if you can get a reference to the Service, you can get the service's TypeMapping which will be guaranteed to have the overridden types registered with it. Otherwise you just don't know which TypeMappings are associated with which Types.

FYI, this is 100% reproducible for me (and fails in the same way each time) so it's not some strange thread safety issue.



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Dan Diephouse - 31/Aug/06 09:16 AM
Sorry I missed this issue before. Scheduling now so I can investigate more in depth.

Dan Diephouse - 02/Sep/06 11:27 PM
I think assumption #1 is correct. Things should only be registered in one type mapping. I'm a bit confused though as to how we could be registering something in multiple type mappings. Any chance you could provide a test case?

Dan Diephouse - 15/Sep/06 01:46 PM