| Summary: | Uninjection order is incorrect when a new value is set after the object has been constructed | ||||||
|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Remy Suen <remy.suen> | ||||
| Component: | E4 | Assignee: | Project Inbox <e4.runtime-inbox> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | P3 | CC: | ob1.eclipse | ||||
| Version: | unspecified | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Windows XP | ||||||
| Whiteboard: | |||||||
| Bug Depends on: | |||||||
| Bug Blocks: | 304847 | ||||||
| Attachments: |
|
||||||
Yep, its a bug. The Computation object removes and then re-adds listener, effectively reordering listeners. I'll need to fix it one way or another. Created attachment 161176 [details]
Patch
The patch changes Computaion and subclasses to only remove listeners then necessary.
Patch applied to CVS Head. Remy, could you let me know if this works for the compatibility problem?
I am keeping the bug open as I am not sure if this is the right approach.
We rely on the order of the listeners. There are two possibilities:
(a) we get listeners originally in the right order and preserve that order through the life of the context; or
(b) we don't maintain order during the life of the context but on the #dispose() / #uninject() sort listeners in the order we need.
The patch above uses path (a). The approach (b) might be safer, but it will require adding a "priority" to listeners and some thinking on whether we want to sort listeners by {object ; priority} or just by {priority}.
(In reply to comment #3) > Patch applied to CVS Head. Remy, could you let me know if this works for the > compatibility problem? Yes, it is okay now, thanks Oleg. I will dupe up bug 304847. *** Bug 304847 has been marked as a duplicate of this bug. *** This has been fixed during Injector refactoring. Now injector construct a independent list of requestors on dispose() / uninject(). |
Technically, this test will not _fail_ because the injection mechanism will merely log the error to the console. public static class InjectTarget3 { Object o; @Inject void set(@Named("inject") Object o) { this.o = o; } @PreDestroy void pd() { assertNotNull(o); } } public void testDispose2() throws Exception { IEclipseContext appContext = EclipseContextFactory.create(); appContext.set("inject", "a"); ContextInjectionFactory.make(InjectTarget3.class, appContext); appContext.set("inject", "b"); ((IDisposable) appContext).dispose(); }