CacheFactory.CacheNotFoundException error on fwreinit

77 views
Skip to first unread message

James Buckingham

unread,
Nov 9, 2010, 10:39:49 AM11/9/10
to ColdBox Platform
Hi group,

I've come across this error that seems to just happening when I
reinitialise on a particular handler. The error is:

Application Execution Exception
Error Type: CacheFactory.CacheNotFoundException : [N/A]
Error Messages: Cache default is not registered.
Valid cache names are

Coming from:-

ID: CFTHROW
LINE: 191
Template: C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\cache
\CacheFactory.cfc

The project entry point into the framework is a function call coming
from an object I have in the session. This function is calling
lightwire and ask for an iterator. Code is ....

<cfset var objIterator =
getColdBox().getPlugin('ioc').getBean('arrayIterator') />

... and the Lightwire config settings are....

<bean id="arrayIterator" class="model.tools.iterators.arrayIterator"
lazy-init="false" singleton="false" />

I've tried tweaking these but I can't seem to shift this error.

Just for extra info - This is the first call I've made to this object
since it entered the session. I used it on the previous handler but
it's not saved into the session until that handler has successfully
finished everything.

If I reinitialise on any other event things are fine and refresh, it's
just this one that seems to have a problem. Have I maybe configured
Lightwire wrong?

Any help appreciated.

Cheers,
James

Luis Majano

unread,
Nov 9, 2010, 1:38:38 PM11/9/10
to col...@googlegroups.com
Hmm, not sure what this could be, but if your object is in session and not within a coldbox lifecycle event, then it needs to communicate directly with the controller in the application scope via a ColdBox proxy or something.  Much how detached objects are in cf9 orm.  This might be the culprit, but not sure.  As the error you get is when there is no default cache defined, which is impossible in a coldbox app.  So it might be a reference-persistence issue.

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


On Tue, Nov 9, 2010 at 7:39 AM, James Buckingham <clar...@gmail.com> wrote:
getColdBox

James Buckingham

unread,
Dec 22, 2010, 6:47:02 AM12/22/10
to col...@googlegroups.com
Hi Luis,

Going back little bit here and firstly sorry for not replying. Got lost in the workload and forgot to come back to you.

Think I've worked out what the problem is here.

I'm working on a VM, dual screen setup. So I do development in the VM but run my browser from my local. I access my VM through its IP address with this address:-


The error above seems to happen when I fwreinit on particular handlers on this address, yet when I go on the VM and use the browser localhost address I don't.

I can only assume that by going in on IP I'm using a different environment setup to what I'm getting on localhost. Localhost = Development, IP = Production (default).

Don't know if that gives any insight as to what might be going on but if you want the full stack trace for all this see below. 

Cheers,
James

----

Tag Context:
ID:CFTHROW
LINE:191
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\cache\CacheFactory.cfc
ID:CF_TEMPLATEPROXY
LINE:127
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\web\Controller.cfc
ID:CF_TEMPLATEPROXY
LINE:60
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\web\services\BaseService.cfc
ID:CF_UDFMETHOD
LINE:356
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\web\services\PluginService.cfc
ID:CF_UDFMETHOD
LINE:127
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\web\services\PluginService.cfc
ID:CF_TEMPLATEPROXY
LINE:350
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\web\Controller.cfc
ID:CF_TEMPLATEPROXY
LINE:6
Template:C:\Inetpub\Enrolnow\www\model\enrolment\enrolment.cfc
ID:CF_UDFMETHOD
LINE:30
Template:C:\Inetpub\Enrolnow\www\model\enrolment\enrolment.cfc
ID:CF_TEMPLATEPROXY
LINE:55
Template:C:\Inetpub\Enrolnow\www\handlers\Personal.cfc
ID:CFINVOKE
LINE:662
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\web\Controller.cfc
ID:CF_UDFMETHOD
LINE:553
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\web\Controller.cfc
ID:CF_TEMPLATEPROXY
LINE:226
Template:C:\Inetpub\common\ColdBox\v3.0.0 RC1 (vendor)\system\Coldbox.cfc
ID:CF_TEMPLATEPROXY
LINE:69
Template:C:\Inetpub\Enrolnow\www\Application.cfc

James Buckingham

unread,
Dec 23, 2010, 10:22:58 AM12/23/10
to col...@googlegroups.com
Ok scrap what I said yesterday... it was a load of waffle that had nothing to do with the problem :-D. About 10 minutes after I wrote that it started on the local machine.

The problem, and I do believe I've fixed it, is this...

I've got two Transfer objects in session. These objects on initialisation are injected with a reference to the ColdBox framework.

In the stack trace above you'll see a reference to line 6 of the enrolment object, which is one of these objects. That was actually a call to the IoC plugin to load in a new object.

What seemed to be happening was when I reinitialised the reference to the ColdBox, which I'm assuming is involved with the CacheFactory in someway, within these objects is suddenly lost. I don't know if the ColdBox is given a new location / id in the Factory but whatever is happening the enrolment object is asking for CB and the CacheFactory doesn't know what it's talking about. 

As a side note I was also noticing that I was losing the sessions when the fwreinit happened.

Anyway just to say I've removed the injection now ( probably a good thing anyway as I wasn't overly happy with it ) and I'm using a different approaches to what's needed.

I was using the documentation from here for the injection so I don't know if that's something that's hitting just us or could affect others 

Happy Holidays everyone!! :-)

James

br...@bradwood.com

unread,
Jan 8, 2011, 5:14:09 AM1/8/11
to ColdBox Platform
You know, I started getting this error tonight. I've been reinitting
a lot and I do believe it comes from models that I have persisted in
session or application with references to things like the beanFactory.

When I reinit, cachebox shuts down and loads back up. My model in the
application scope stays and still has a reference to the copy of
coldbox which was lying around BEFORE I reinitted. When I try to use
it, cachebox isn't happy because it can't find the cache being
requested any longer.

coldfusion.runtime.CustomException: Cache default is not registered.
at coldfusion.tagext.lang.ThrowTag.doStartTag(ThrowTag.java:124)
at coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2661)
at cfCacheFactory2ecfc597613331$funcGETCACHE.runFunction(C:\websites
\wwwroot\common\coldbox\system\cache\CacheFactory.cfc:186)

I don't know if there's a good answer to this. It kind of makes me
not want to wire my model directly with references to the framework,
and instead break encapsulation and pull the references straight out
of the application scope whenever I need them. If you think about it,
any time you reinit on production, the old instance of the framework
(or most of it anyway) hangs around in memory until the very last
session times out that was active when you reinitted. (assuming you
have models like user objects cached in session with references to
pieces of the framework wired in)

Thoughts?

Thanks!

~Brad
> that's something that's hitting just us or could affect othershttp://wiki.coldbox.org/wiki/Extras:TransferORM.cfm#Bean_Injector_Def...

Luis Majano

unread,
Jan 8, 2011, 11:12:26 AM1/8/11
to col...@googlegroups.com
This is called scope widening injection. Where you cross scope boundaries to get undesired results like you have seen where and old reference remains but has expired from the actual scope. What you need is a middle man that can give you the right reference if you will be putting objects in scope manually.

Basically following a provider pattern to retrieve the scoped reference for you so scope widening is avoided.

I have had many issues with this before and that is why in wirebox I have implemented the provider pattern so you can inject providers to objects. This way the provider does the retrieval across scopes for you.

Since you need a fix now I would suggest that you wire these objects with a proxy to the coldbox factory. Whenever you need cachebox you call your provider to call the factory for it. This way the right reference will be retrieved.

Thoughts?

Sent from my iPhone

> --
> 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

Brad Wood

unread,
Jan 8, 2011, 1:41:34 PM1/8/11
to col...@googlegroups.com
That makes a lot of sense. I'm trying to wrap my head around the actual
implementation though. Where does the provider live? Is it a singleton
that is hanging out in the framework somewhere, or does each instance of my
model get its own little transient provider created for it that has
something along the lines of
application[appKey].cbcontroller.getPlugin("beanFactory") inside of it?

Either way, this proxy provider couldn't hold any direct references to the
framework's bits or it would suffer from the exact same problem. Somewhere
in the line, the reference chain has to be broken by an object who "knows"
the address in the application scope to go ask for things right?

Thanks!

~Brad

Luis Majano

unread,
Jan 8, 2011, 3:48:34 PM1/8/11
to col...@googlegroups.com
Brad

Here  is something you can use now for cachebox.

Create a CFC that will act as your cachebox provider and have one method on it: get().  This provider will be injected in yoru scoped object as part of it. This provider will then be able to talk to the running cf instance.  I will assume it is within the application so you can do something like this:


/**
* CacheBox Provider
*/
component extends="coldbox.system.remote.ColdBoxProxy"{

function get(){
return getCacheBox();
}

}


That's it.  This is a very simple cachebox provider that makes sure it talks to the appropriate scope for retrieval.  So in your scoped component you can inject this provider as a singleton or create it as a transient. I would inject it.  Also, as you can see, you can extend the pattern to make it generic and be able to make the provider more dynamic.  ANyways, this is what is currently being built for wirebox so you can eliminate the scope widening effect also for time persisted services.  Another cool insight into wirebox is you can make methods providers also:

Example,  In your scoped object you can do this:

function getCacheBox() provider="cachebox"{}

That's it.  WireBox will see that you want that method to be a provider for something else.  So it will replace it with a provider method proxy for you, so when you call getCacheBox() locally it actually calls it via a scoped provider.

Thoughts?

-- 

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

br...@bradwood.com

unread,
Jan 8, 2011, 7:47:31 PM1/8/11
to col...@googlegroups.com
> return getCacheBox();

Actually, there's no getCacheBox method in ColdBoxProxy for RC1, but getController().getCacheBox() works nicely.

So basically, it all boils down to the line in ColdBoxProxy that does application[COLDBOX_APP_KEY].  That is how it "knows" where to look without actually holding a hard reference to it.

I created a singleton component called ColdBoxProvider.cfc that extends ColdBoxProxy like you showed and played around wiring it into my model.  For now, I gave it the following methods: getController, getCacheBox, getPlugin, getBeanFactory

Would it make sense to be able to do mixins in your models (or decorate, or sub-class them) so that they always had those ubiquitious methods like getPlugin() and getCacheBox() like all coldbox-family components have such as handlers, interceptors, plugins, etc.  Some people may never touch CB from within their model, but for those of us who do, would it make sense to just put all those methods in all the time?  I don't know-- perhaps that would be a bit heavy-handed invasion of my model but it sure is darn handy to just always have those convenience methods laying around everywhere else in my app.

Or perhaps, use cfpropery autowiring to mixin the methods I needed.  I really like the wirebox concept that you described of putting a place-holder provider method in with metadata describing the fact that it needed to be replaced with an actual provider method.  But honestly, if I know I'm going to need WireBox, CacheBox, and the BeanFactory plugin in my service, I'd rather continue to define that the cfproperty metadata as opposed to place-holder methods.  The bottom line is, I want it to be as LITTLE code as possible to actually use these proxied objects.

This is what I have currently, which is the most convenient, but doesn't use a provider  (uses cfproperty tags for injection to variables scope)
<cfset foo = cacheBox.get("bar")>

This would be the next best thing: (assumes provider methods have been mixed-in somehow)
<cfset foo = getCacheBox().get("bar")>

This would work, but getting more cumbersome: (assumes my ColdBoxProvider has been wired into the variables scope)
<cfset foo = coldBoxProvider.getCacheManager().get("bar")>

You know, I could even stick with my ColdBoxProvider pattern and inject in specific provider methods directly with the "model:{name}:{method}" DSL if the method I wired simply returned a reference to the provider method I needed.  That would require no more code than my second example, but would still require me to specify a cfproperty tag for each provider method I planned on using.

So, it's really a matter of how those provider methods get there, and if you only mixin the ones you'll need, or just slap them all in so any piece of my model has full proxied-access to ColdBox.  Autowiring performance would be one concern, of course.

I think my preferred solution (with only a small amount of thought at this point in time) would be an autowiring DSL that allowed for a collection of pre-defined provider methods to be wired into your components like this:

<cfproperty name="getCacheBox" inject="coldbox:provider:cacheBox" scope="variables" />  

<cfproperty name="getWireBox" inject="coldbox:provider:wireBox" scope="variables" />  


In the above hypothetical component, I would then have access to a getCacheBox() and getWireBox() method which was a provider method for the corresponding ColdBox object.

Thanks!

~Brad


Luis Majano

unread,
Jan 8, 2011, 7:51:18 PM1/8/11
to col...@googlegroups.com
Totally understand.  I think that you can do a very simple interceptor that listenes to afterModelCreation and wires up your models with coldbox capabilities like you want it, this way its non-invasive and ran at runtime.

-- 
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

br...@bradwood.com

unread,
Jan 8, 2011, 8:21:52 PM1/8/11
to col...@googlegroups.com
Ooh, got to love the interceptor approach.  I always forget about some of those interception points.

I still think it would be cool to have a core setting though to wire your model with ColdBox provider methods.

Thanks!

~Brad
-------- Original Message --------
Subject: [coldbox:7593] Re: CacheFactory.CacheNotFoundException error
on fwreinit

Luis Majano

unread,
Jan 9, 2011, 2:07:01 AM1/9/11
to col...@googlegroups.com

Well why not. Can we spec this for the next release. Maybe a base model class?

On Jan 8, 2011 5:21 PM, <br...@bradwood.com> wrote:
Reply all
Reply to author
Forward
0 new messages