Stack Overflow Error - BeanFactory

60 views
Skip to first unread message

Aaron Greenlee

unread,
Jun 29, 2010, 1:18:33 PM6/29/10
to ColdBox Platform
This message is part question and part sharing to help anyone else who
may encounter this.

I've spent more than a day fighting with a Stack Overflow error in a
new ColdBox - ColdFusion 9 Application. I am using the Auto-wire
dependency injection system native to ColdBox. I finally identified
the area of concern and have resolved issue; however, I am still not
exactly sure why this happened, and, have a little concern it could
pop up.

This is the code that directly caused the Stack Overflow Error.
<!---
-----------------------------------------------------------------------------------------------------
--->

<cfset var languages = [] />
<cfset var i = 0 />
<cfloop query='q.languages'>
<cfset i++ />
<cfset var Language = dependency.BeanFactory.getModel('Language') /
>
<cfset
dependency.BeanFactory.populateFromQuery(target=language,qry=q.languages,rowNumber=i) /
>
<cfset arrayAppend(languages, Language) />
</cfloop>
<cfset arguments.User.setLanguages(languages) />

<!---
-----------------------------------------------------------------------------------------------------
--->
This is the code that resolved the StackOverflow error
<!---
-----------------------------------------------------------------------------------------------------
--->

<cfset var languages = [] />
<cfset var i = 0 />
<cfloop query='q.languages'>
<cfset i++ />
<cfset arrayAppend(languages,
dependency.BeanFactory.populateFromQuery(
target='shared.models.objects.Language'
,qry=q.languages,rowNumber=i) ) />
</cfloop>
<cfset arguments.User.setLanguages(languages) />

<!---
-----------------------------------------------------------------------------------------------------
--->

I spent a lot of time evaluating all my dependencies to verify I did
not have two objects that both relied on each other fearing it could
have caused some kinda of infinite loop. I've verified that the loop
over the query in the first code example is valid.

Then, I thought, the Bean Factory (which does a lot of work for me...
thanks ColdBox) may need a larger stack size, but, even when I
increased the Java and Native stack-size via the JVM args -ss and -oss
to crazy/stupid high values, there error persisted.

The Question...
Any thoughts on what I may have done wrong, or, why the Bean Factory
could go into some infinite loop given the same code provided?

I would prefer to use the code posted first to allow my to auto-wire
the Language object in the future. Currently, there is no need to do
so, but, you never know.

Thanks All!

Aaron Greenlee
http://aarongreenlee.com

John Whish

unread,
Jun 29, 2010, 1:39:34 PM6/29/10
to col...@googlegroups.com

Complete stab in the dark but have you tried moving the "varing" of language outside of the loop and just set inside the loop?

-- sent by a little green robot


--
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
To post to this group, send email to col...@googlegroups.com
To unsubscribe from this group, send email to coldbox-u...@googlegroups.com
For more options, visit this group at http://groups-beta.google.com/group/coldbox
For News, visit http://blog.coldbox.org
For Documentation, visit http://wiki.coldbox.org

Aaron Greenlee

unread,
Jun 29, 2010, 2:49:16 PM6/29/10
to ColdBox Platform
Thanks for the reply, John. I tried the following two methods based on
you response and both also had stack overflow errors.

var languages = [];
var lanuage = '';
var i = 0 ;
var n = arguments.qry.recordCount;
for (i=1; i<= n; i++) {

language = dependency.BeanFactory.getModel('Language');

dependency.BeanFactory.populateFromQuery(target=language,qry=qry,rowNumber=i);
arrayAppend(languages, dependency.BeanFactory.getModel('Language'));
}

/* AND */

var languages = [];
var lanuage = '';
var i = 0 ;
var n = arguments.qry.recordCount;
for (i=1; i<= n; i++) {
arrayAppend(languages, dependency.BeanFactory.getModel('Language'));

dependency.BeanFactory.populateFromQuery(target=languages[i],qry=qry,rowNumber=i);
}

/* for those interested, here is the language object */


/
*-------------------------------------------------------------------------
Author : Aaron Greenlee (aa...@wreckingballmedia.com)
Date Created : 6/16/2010 7:46:38 PM
Modified : N/A
Description : Represents a language.

--------------------------------------------------------------------------
*/

/** @hint Represents a language. */
component name='Language' accessors=true autowire=false
table='system_languages' {

property name='lid' ormtype='numeric' persistent=true;
property name='language' ormtype='char' persistent=true;
property name='language_short' ormtype='char' persistent=true;
property name='language_medium' ormtype='char' persistent=true;
property name='akamai_directory' ormtype='char' persistent=true;
property name='iso_code' ormtype='char' persistent=true;
property name='is_system_language' ormtype='boolean' persistent=true;

public function init (
numeric lid
,string language
,string language_short
,string language_medium
,string akamai_directory
,string iso_code
,boolean is_system_language
) {

if (structKeyExists(arguments, 'lid'))
setLID(arguments.lid);

if (structKeyExists(arguments, 'language'))
setLanguage(arguments.language);

if (structKeyExists(arguments, 'Language_Short'))
setLanguage_Short(arguments.Language_Short);

if (structKeyExists(arguments, 'Language_Medium'))
setLanguage_Medium(arguments.Language_Medium);

if (structKeyExists(arguments, 'Akamai_Directory'))
setAkamai_Directory(arguments.Akamai_Directory);

if (structKeyExists(arguments, 'ISO_Code'))
setISO_Code(arguments.ISO_Code);

if (structKeyExists(arguments, 'is_system_language'))
setIs_System_Language(arguments.is_system_language);

return this;
}

/** Facade Method for getIs_System_Langauge. Used to keep API
consistent. */
public boolean function isSystemLanguage() {
return getIs_System_Language();
}
}

Mark Mandel

unread,
Jun 29, 2010, 6:07:07 PM6/29/10
to col...@googlegroups.com
What's the actual error?

Is it in ColdSpring, or in Coldbox?

Without knowing the loop that the StackOverflow is going through, I'm not sure what we can do to help.

Mark


--
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
To post to this group, send email to col...@googlegroups.com
To unsubscribe from this group, send email to coldbox-u...@googlegroups.com
For more options, visit this group at http://groups-beta.google.com/group/coldbox
For News, visit http://blog.coldbox.org
For Documentation, visit http://wiki.coldbox.org



--
E: mark....@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

cf.Objective(ANZ) - Nov 18, 19 - Melbourne Australia
http://www.cfobjective.com.au

Hands-on ColdFusion ORM Training
www.ColdFusionOrmTraining.com

Aaron Greenlee

unread,
Jun 29, 2010, 6:18:36 PM6/29/10
to col...@googlegroups.com
Following, please find the full stack trace. The last CFC shifts between the InterceptorState and BeanFactory.

To clarify, I am using ColdBox's DI solution exclusively. ColdSpring is not involved.


coldfusion.runtime.EventHandlerException: Event handler exception.
	at coldfusion.runtime.AppEventInvoker.onRequestStart(AppEventInvoker.java:266)
	at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:331)
	at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
	at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
	at coldfusion.filter.PathFilter.invoke(PathFilter.java:87)
	at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:27)
	at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
	at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
	at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
	at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
	at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
	at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
	at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:53)
	at coldfusion.CfmServlet.service(CfmServlet.java:200)
	at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
	at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
	at com.intergral.fusionreactor.filter.FusionReactorFilter.b(FusionReactorFilter.java:376)
	at com.intergral.fusionreactor.filter.FusionReactorFilter.c(FusionReactorFilter.java:254)
	at com.intergral.fusionreactor.filter.FusionReactorFilter.doFilter(FusionReactorFilter.java:164)
	at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
	at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
	at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
	at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
	at jrun.servlet.FilterChain.service(FilterChain.java:101)
	at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
	at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
	at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
	at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
	at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
	at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)
	at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
	at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)
	at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
Caused by: java.lang.StackOverflowError
	at coldfusion.tagext.lang.InvokeTag.doEndTag(InvokeTag.java:475)
	at cfInterceptorState2ecfc906489402$funcINVOKER.runFunction(C:\inetpub\wwwroot\coldbox\system\beans\InterceptorState.cfc:127)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
	at coldfusion.filter.SilentFilter.invoke(SilentFilter.java:47)
	at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405)
	at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
	at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
	at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
	at coldfusion.runtime.CfJspPage._invokeUDF(CfJspPage.java:2582)
	at cfInterceptorState2ecfc906489402$funcPROCESS.runFunction(C:\inetpub\wwwroot\coldbox\system\beans\InterceptorState.cfc:80)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
	at coldfusion.filter.SilentFilter.invoke(SilentFilter.java:47)
	at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405)
	at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
	at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
	at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
	at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:490)
	at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:336)
	at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2360)
	at cfInterceptorService2ecfc327319666$funcPROCESSSTATE.runFunction(C:\inetpub\wwwroot\coldbox\system\services\InterceptorService.cfc:98)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
	at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405)
	at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
	at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
	at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
	at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:490)
	at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:336)
	at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2360)
	at cfColdbox2ecfc255186317$funcPROCESSCOLDBOXREQUEST.runFunction(C:\inetpub\wwwroot\coldbox\system\Coldbox.cfc:195)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
	at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405)
	at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
	at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
	at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
	at coldfusion.runtime.CfJspPage._invokeUDF(CfJspPage.java:2582)
	at cfApplication2ecfc2122324858$funcONREQUESTSTART.runFunction(C:\inetpub\wwwroot\htdocs\cmscb\Application.cfc:55)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
	at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405)
	at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
	at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
	at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
	at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
	at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:490)
	at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:336)
	at coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:88)
	at coldfusion.runtime.AppEventInvoker.onRequestStart(AppEventInvoker.java:258)
	... 32 more

Luis Majano

unread,
Jun 29, 2010, 6:28:01 PM6/29/10
to col...@googlegroups.com
the stack shows the interceptors firing? 

any more info here?

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Aaron Greenlee

unread,
Jun 29, 2010, 6:48:40 PM6/29/10
to col...@googlegroups.com
There is a Request.cfc Interceptor which reads a setting from the ColdBox Config and constructs any objects required to fullful a basic request (currently: Site, User). This issue is triggered by User.

Here are User's dependencies:

property name='BeanFactory' type='coldbox:plugin:BeanFactory' setter=false getter=true;
property name='UserDAO' type='model' setter=false getter=true;
property name='i18nDAO' type='model' setter=false getter=true;
property name='RoleDAO' type='model' setter=false getter=true;

The user is first Constructed to be a 'New User' and then, if the proper conditions exist, the Request.cfc Interceptor will ask the User to self-populate. When I first had this issue. Here is the Populate() method within User.

  /** Populate the User from the database. @property Define the criteria to use. Accepts 'login' and any valid User property. Example : 'user_id' or 'email'. */ public boolean function populate (string property='User_ID') { arguments.User = this; if (UserDAO.populate(argumentCollection=arguments)) variables.populated = true; else variables.populated = false; return variables.populated; }

And, here is a condensed version of UserDAO's populate method:

<!--- PUBLIC METHODS ---------------------------------------------------------------------------> <cffunction name="populate" returntype='boolean' hint="Populates a User provided as an argument using the email and password stored within the Object."> <cfargument name='User' required='true' hint="A user object with the email and password set." /> <cfargument name='Property' default="login" required='false' hint="If defined, the specified property will be used to select the user." /> <!--- Validate the API ---> <cfif !arrayContains(variables.allowedPopulateProperties, lcase(arguments.Property) )> <cfthrow message='Invalid Argument' detail='The property argument "#arguments.Property#" is invalid. Allowed values are "#arrayToList(variables.allowedPopulateProperties, ', ')#".' type='shared.models.DAOs.UserDAO.populate()' errorcode='API' /> </cfif> <cfset var q = {} /> <cfquery name="q.select"> SELECT XXXX
</cfquery>
<cfif q.select.recordCount EQ 0> <cfreturn false /> </cfif> <!--- Populate singular properties ---> <cfset dependency.BeanFactory.populateFromQuery(target=User,qry=q.select) /> <!--- Now, pull and populate languages available ---> <cfset dependency.i18nDAO.populateUserLanguages(User) /> <cfreturn true /> </cffunction>

The populateUserLanguage() method is where I finally found a resolution. By rewriting the method as I previously posted, the error goes away. I also rewrote this behavior and placed the burden of creating/populating these language objects in a few other places and always received the same stack overflow error.

Thanks,

Aaron Greenlee

Aaron Greenlee

unread,
Jun 29, 2010, 7:10:46 PM6/29/10
to col...@googlegroups.com
To further clarify, I've now tested by removing the BeanFactory from the creation of the new Object and still the error is caused.

// Create the Language
language = new shared.models.objects.Language();
// Old Method: language = dependency.BeanFactory.getModel('Language');

// This line still causes the Stack Overflow.
dependency.BeanFactory.populateFromQuery(target=language,qry=qry,rowNumber=i);

Aaron Greenlee

unread,
Jul 1, 2010, 3:02:03 PM7/1/10
to ColdBox Platform
I now have more information about this error. Seems, the bean is the
cause.

If the INIT method of the Language object has arguments defined, the
stack error occurs. If I remove the arguments from the constructor, it
works as expected.

I also defaulted every argument and still got the error. Here is the
BAD code... any thoughts?

/** @hint Represents a language. */
component name='Language' accessors=true autowire=false
table='system_languages' cache=false singleton=false {

property name='lid' ormtype='numeric' persistent=true;
property name='language' ormtype='char' persistent=true;
property name='language_short' ormtype='char' persistent=true;
property name='language_medium' ormtype='char' persistent=true;
property name='akamai_directory' ormtype='char' persistent=true;
property name='iso_code' ormtype='char' persistent=true;
property name='is_system_language' ormtype='boolean' persistent=true;

/** Constructor. Languages should allways be populated during
construction or just after.
The default language is 'ENGLISH' */
public function init () {

// Construct the language using arguments.
setLID(arguments.lid);
setLanguage(arguments.language);
setLanguage_Short(arguments.Language_Short);
setLanguage_Medium(arguments.Language_Medium);
setAkamai_Directory(arguments.Akamai_Directory);
setISO_Code(arguments.ISO_Code);

John Whish

unread,
Jul 2, 2010, 5:26:06 AM7/2/10
to col...@googlegroups.com
Is this a persistent CFC? I'm a bit confused as you have the table attribute, but not the persistent="true" attribute. 


/** @hint Represents a language. */
component name='Language' accessors=true autowire=false
       table='system_languages' cache=false singleton=false {


Luis Majano

unread,
Jul 2, 2010, 12:11:33 PM7/2/10
to col...@googlegroups.com
Also, what where the constructor arguments?

Maybe you had a circular reference there the wiring was trying to detect.

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com


Reply all
Reply to author
Forward
0 new messages