CacheFactory.CacheNotFoundException error on fwreinit

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

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

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

http://10.xx.xx.xx/myproject

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

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
http://wiki.coldbox.org/wiki/Extras:TransferORM.cfm#Bean_Injector_Definition

Happy Holidays everyone!! :slight_smile:

James

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

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?

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

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?