[ColdBox 4.0] SES error w/ cbstorages

I am trying to move our app to 4.0 and have run into some errors. Mostly compatibility issues which I have been able to resolve except:

Error building: interceptor-SES -> Requested instance not found: ‘sessionStorage@cbstorages’ The instance could not be located in any declared scan location(s) (pms-es.models) or full path location with constructor arguments: {controller={[(Component=coldbox.system.web.Controller)]},properties={{}}}

I have installed cbstorages in my modules folder and other code seems to be using it correctly. Any ideas? Thanks!

Forgot to mention I have:

sessionStore = getInstance(‘sessionStorage@cbstorages’);

In my ApplicationHelper.cfm file

Are you using this in the routes.cfm?

Luis Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com
P/F: 1-888-557-8057
Direct: (909) 248-3408

ColdBox Platform: http://www.coldbox.org

ContentBox Platform: http://www.gocontentbox.org
Linked In: http://www.linkedin.com/pub/3/731/483

Social: twitter.com/ortussolutions | twitter.com/coldbox | twitter.com/lmajano | twitter.com/gocontentbox

Basically using the default routes.cfm except for a http or https param based on the environment…

// Allow unique URL or combination of URLs, we recommend both enabled setUniqueURLS(false); // Auto reload configuration, true in dev makes sense to reload the routes on every request //setAutoReload(false); // Sets automatic route extension detection and places the extension in the rc.format variable // setExtensionDetection(true); // The valid extensions this interceptor will detect // setValidExtensions('xml,json,jsont,rss,html,htm'); // If enabled, the interceptor will throw a 406 exception that an invalid format was detected or just ignore it // setThrowOnInvalidExtension(true);

// Base URL
// ** Note: IIS URL Rewrite can be used to removed index.cfm from the URL
if( len(getSetting(‘AppMapping’) ) lte 1){
setBaseURL("#getSetting(‘urlPrefix’)#://#cgi.HTTP_HOST#/index.cfm");
}
else{
setBaseURL("#getSetting(‘urlPrefix’)#://#cgi.HTTP_HOST#/#getSetting(‘AppMapping’)#/index.cfm");
}

// Your Application Routes
addRoute(pattern=":handler/:action?");

/** Developers can modify the CGI.PATH_INFO value in advance of the SES
interceptor to do all sorts of manipulations in advance of route
detection. If provided, this function will be called by the SES
interceptor instead of referencing the value CGI.PATH_INFO.

This is a great place to perform custom manipulations to fix systemic
URL issues your Web site may have or simplify routes for i18n sites.

@Event The ColdBox RequestContext Object
*/
function PathInfoProvider(Event){
/
Example:
var URI = CGI.PATH_INFO;
if (URI eq “api/foo/bar”)
{
Event.setProxyRequest(true);
return “some/other/value/for/your/routes”;
}
*/
return CGI.PATH_INFO;
}

Hmm, the only thing it might seem a chicken and the egg scenario. Do you have a sample you can share with us?

Luis Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com
P/F: 1-888-557-8057
Direct: (909) 248-3408

ColdBox Platform: http://www.coldbox.org

ContentBox Platform: http://www.gocontentbox.org
Linked In: http://www.linkedin.com/pub/3/731/483

Social: twitter.com/ortussolutions | twitter.com/coldbox | twitter.com/lmajano | twitter.com/gocontentbox

A work-a-round I have in place in ApplicationHelper.cfm now is…

try { sessionStore = getInstance('SessionStorage@cbstorages'); clientStore = getInstance('ClientStorage@cbstorages'); msg = getInstance('messagebox@cbmessagebox'); } catch (any e) { }

//Asking logbox for the root logger
log = logBox.getRootLogger();
helpDeskNo = getSetting(“helpDeskNo”);

My reason for these are so I don’t have to use getInstance(‘xxx@xxx’) throughout… unless there is some easier way to do to have universal variables throughout the app?

It runs but I can see the below exception gets thrown…

Injector.InstanceNotFoundException - in C:/ColdFusion10/cfusion/wwwroot/coldbox/system/ioc/Injector.cfc : line 236

	    Requested instance not found: 'SessionStorage@cbstorages'

Ahh I see what you are trying to do.

Unfortunately, you are trying to execute this, when modules are not loaded yet. The chicken and egg problem.
This is because the application helper gets injected in handlers, interceptors and the like. I would not encourage the use of many global variables due to the fact that it is hard to debug.

However, you can delay construction of dependencies by using providers, so you don’t have to use the try/catch:

sessionstore = getInstance( dsl=“provider:sessionStorage@cbstorages” );

clientStore = getInstance( dsl=“provider:ClientStorage@cbstorages” );

This tells WireBox to inject a provider of such dependency and delay construction.

Luis Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com
P/F: 1-888-557-8057
Direct: (909) 248-3408

ColdBox Platform: http://www.coldbox.org

ContentBox Platform: http://www.gocontentbox.org
Linked In: http://www.linkedin.com/pub/3/731/483

Social: twitter.com/ortussolutions | twitter.com/coldbox | twitter.com/lmajano | twitter.com/gocontentbox

OK thanks… I will try that. My reason for the helper is because we have a lot of session variables in a legacy app which we are going to be converting to ColdBox and it seemed to make sense to have a shortened variable to call for session variables. Are there any other ways you think of which may be better?

IMHO, this is perfect use for a request context decorator:

component entityname=“RequestDecorator” output=“false” extends=“coldbox.system.web.context.RequestContextDecorator” {
property name=“controller”;
property name=“event”;

public void function configure(){
var prc = event.getCollection(private=true);
prc.sessionStore = getInstance(‘SessionStorage@cbstorages’);
prc.clientStore = getInstance(‘ClientStorage@cbstorages’);
prc.msg = getInstance(‘messagebox@cbmessagebox’);

//Asking logbox for the root logger
prc.logger = logBox.getRootLogger();
prc.helpDeskNo = getSetting(“helpDeskNo”);

}

}

If you need to inject the instance in to your models, you can add a decorator to those as well.

component entityname=“ORMDecorator” output=“false” extends=“cborm.models.ActiveEntity” {
property name=“sessionStore” inject=“SessionStorage@cbstorages”;
(etc…)
}

Luis is correct. Now that we have modularized ColdBox, application startup is a sticky process. Depending on the order that all the modules are loaded up, it’s possible that other parts of the framework might try to access them before they exist. We could rearrange the startup order to fix one scenario, but it would simply create another issue elsewhere since something has to get loaded first.

Perhaps we should document a list of all the things that load before modules do to help people avoid these scenarios. I’ll also point out the module service has a method called “isModuleActive()” that allows you to check and see if a given module has been loaded prior to using it. Of course, I think Luis’s provider suggestion is still better, since checking “isModuleActive()” might just lead to your variables not existing unexpectedly.

I actually noticed this and put in this ticket so we could discuss options. This ticket is about autowiring a modules models into an interceptor. Since the applicationHelper is run on interceptor creation, your issue is pretty much the same thing:
https://ortussolutions.atlassian.net/browse/COLDBOX-417

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Thanks, Luis’ suggestion is working fine. I will also test out what Jon suggested.

I created a request decorator and placed it in my models folder. I get the following error:

Messages: Variable GETINSTANCE is undefined.

If I put the code into the configure function in system RequestContextDecorator.cfc file the error does not happen. Any suggestions?

Thanks,
Chad

Oops. Sorry about that. I should have tested that code in a live RCD. You need to pull wirebox and logbox in via your controller. It should be:

public void function configure(){
var wirebox=controller.getWirebox();
var prc = event.getCollection(private=true);
prc.sessionStore = wirebox.getInstance(‘SessionStorage@cbstorages’);
prc.clientStore = wirebox.getInstance(‘ClientStorage@cbstorages’);
prc.msg = wirebox.getInstance(‘messagebox@cbmessagebox’);

//Asking logbox for the root logger
prc.logger = controller.getLogBox().getRootLogger();
prc.helpDeskNo = controller.getSetting(“helpDeskNo”);
}

All good now. It did not like the controller property so I had to use getController() in place of controller

Thanks!

> Variable GETINSTANCE is undefined.

That’s because there’s no getInstance() method in the request context or it’s decorator. This is due to the fact that it doesn’t extend the frameworksupertype. I don’t know if there’s a really good reason why it doesn’t-- Luis would need to address that. You have the controller available to you. Ask it for wirebox, and proceed from there.

> If I put the code into the configure function in system RequestContextDecorator.cfc file the error does not happen.

Well, that’s most likely because your configure method isn’t calling super.configure() which means it never gets run, and therefore “doesn’t error”.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Look at the source code! It’s instance.controller, not controller (which will search the variables scope). The getController() method is just a convenience method in the decorator to get instance.controller for you.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Ohh ok… thanks!

I have an app running 4.3 and all runs well (i’ll update this to 5.x but been busy updating the other apps) but periodically the app starts showing an error that the requested instance sessionStorage@cbstoreages can not be located in any declared scan locations. I reinit the app and all is well for some period of time. I don’t have any fancy scan locations.

Any ideas?

Example code in main.cfc where the error is ocurring:

component {
property name=“sessionStorage” inject= “provider:sessionStorage@cbstorages”;

public void function onRequestStart(event)
{
//set the session for client
if (getInstance(‘sessionStorage@cbstorages’).getVar(‘clientid’) lt 1) // error is being thrown here
{
do some stuff
}

Is ti the injection that’s failing, or the getinstance call? I can’t tell without the stack trace. Please include the full error.