Ticket #193 (closed defect: fixed)
The restoreAfterUnmarshal() method may observe uninitialized objects
| Reported by: | Bernhard Haumacher (haui at haumacher dot de) | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | 1.09b |
| Component: | uka.transport | Version: | |
| Severity: | normal | Keywords: | |
| Cc: |
Description
The package uka.transport supports custom restore methods that are called automatically when an object is unmarshaled (see ticket:162). This method is intended e.g. for initializing transient object state. Unfortunately, the execution of such method may access other objects that are not completely initialized (either the restoreAfterUnmarshal() method may not yet be called on a referenced object, or a referenced object may not even have its references to other objects initialized).
Evaluation
Obviously, in cyclic graphs, where each object has a custom restoreAfterUnmarshal() method, it is impossible to guarantee that all referenced objects are completely initialized (all restoreAfterUnmarshal() methods are called on the referenced objects) before the restoreAfterUnmarshal() method is called on some object.
Evaluation
Only with ticket 174 (non-recursive marshaling) and ticket 191 (non-recursive deep cloning), it might occur that the restoreAfterUnmarshal() method is called on an object that has references to other objects that have still uninitialized references. The only way to circumvent this problem is to add a third pass to the unmarshaling and cloning process that is exclusively responsible for calling the restoreAfterUnmarshal() methods on objects that require it.
Solution
The restoreAfterUnmarshal() method is now called after unmarshaling or cloning the complete graph on those objects that require it. An object can expect that all objects reachable by "forward" references (in marshaling order) are already completely initialized, when the restoreAfterUnmarshal() method is called.
Test
uka.test.transport.TestRestore
fixed since 1.09b.
