Bug in initialization of bean factory aware objects

8 views
Skip to first unread message

Sean Corfield

unread,
Aug 6, 2009, 4:09:50 AM8/6/09
to coldspri...@googlegroups.com
I just ran into an interesting bug with ColdSpring / Reactor that I
wanted to share to get feedback on...

In DefaultXmlBeanFactory.cfc, around lines 865-900, there's a loop
over the function metadata to call init() on the new object. The loop
says:

if method is init then
. . . call object.init with the appropriate arguments . . .
else if method is setBeanFactory then
. . . call object.setBeanFactory() with ColdSpring as the argument . . .

Now consider an object that has both init() and setBeanFactory() - you
can't tell what order ColdSpring will call these two functions...
which means that setBeanFactory() had better not depend on init()
having been called!

Reactor's main factory has a setBeanFactory() method that does indeed
depend on init() having been called - to set it's internal object
factory, into which it injects the external bean factory when
ColdSpring calls setBeanFactory() on it.

Strangely this was working fine on Railo but failed on CF8 because the
metadata had the functions in a different order.

The fix seems to be:
- split the loop into two loops:
-- first loop looks for init() and calls it
-- second loop looks for setBeanFactory() and calls it
(an optimization would be to loop once and set flags for hasInit and
hasSetBeanFactory and then just conditionally call them in that order)

Thoughts?
--
Sean A Corfield -- (904) 302-SEAN
Railo Technologies US -- http://getrailo.com/
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Dennis Clark

unread,
Aug 6, 2009, 8:37:52 PM8/6/09
to coldspri...@googlegroups.com
Nice catch Sean! I've had problems with that exact piece of code before,
but couldn't quite put my finger on what was wrong with it. You
reasoning explains perfectly the troubles I had with it.

Last year I wrote a simple ValidatFactory.cfc so I could configure
Validat from within ColdSpring. Validat itself uses ColdSpring for its
internal objects, and I wanted my factory to to be able to reference the
BeanFactory that defined it to link it to Validat's internal factory.
However I found that sometimes got "variable undefined" errors when
invoking my ValidatFactory, and I decided that init() and
setBeanFactory() just did not work well together in a ColdSpring bean.
It now makes sense that sometimes init() and setBeanFactory() were
sometimes not being called in the correct order. My workaround at the
time was to eliminate init() from my CFC and define my own init-method
(which is executed after the metadata loop).

I prefer your optimized solution to your two-loop solution. Either way,
I would definitely like to see this fixed in ColdSpring.

Cheers,

-- Dennis

Reply all
Reply to author
Forward
0 new messages