Dependency Injection Failures in CB 3.5.2

*** Sorry for the repost but didn’t hear any ideas from anyone and not sure if got through*

I am running into an occasional issue in CB 3.5.2, running under CF 11 on a Windows 2008 R2 platform. Following is a screenshot of the LogBox output:

All of these objects are injected via CF properties component script and 99% of the time, don’t have any issues. Occasionally; however, they just stop working. Adding the URL fwreinit, resetting the application, resolves the issue, for a while, sometimes days.

One item that is really strange is line 2996 in the above, which is saying that the LOGGER does not exist. This error is being logged by the LOGGER; however, in the base platform class for our implementation via a different injection.

Following is a sample of the injection code for one of our services:

/* Class Properties */
property name="sysdb"           inject="coldbox:datasource:sysdb"     scope="instance";
property name="controller"       inject="coldbox"                  scope="instance";
property name="UtilityService"    inject="model:UtilityService"        scope="instance";
property name="DictionaryService"   inject="model:DataDictionaryService"    scope="instance";
property name="SearchQueriesHelper" inject="model:helpers.SearchQueries"    scope="instance";
property name="LanguageService"     inject="model:LanguageService"          scope="instance";
property name=**“**LOGGER"              inject="Logbox:logger:{this}"           scope="variables";

Ideas, anyone?

Kevin S. Anderson
Software Engineer
Intelligent Software Solutions Inc.

Kevin,

I’d help if I could, but the screenshot doesn’t give me much to go on. A few questions that spring to mind:

  • Are you calling for LOGGER from the init() method before the instance has been created? If so, is there inheritance or are you calling super.init() before or after the call for LOGGER?

  • It looks like, in the error, you’re calling it as LOGGER only and not through the variables scope or accessor method? What happens when you call it via the accessor method? The reason I ask is that CF will say it does not exist if it has not been injected, but calling it via the accessor method will return a java null if injection has not occurred so you’ll be able to see if it’s a local scope issue or an auto wiring issue.

Can you paste in the function wrapper that’s calling for it? That might help to

The quick and dirty solution to prevent the error is simply to test for the injected property and autowire if they don’t exist.

if(isNull(getLOGGER() and structKeyExists(application,'wirebox')){
    application.wirebox.autowire(this);
}

The long-term solution is to figure out why LOGGER is being called before the auto wiring is completed.

Jon

Sorry, that should be “Can you paste in the function wrapper that’s calling for it? That might help to diagnose the issue more effectively.” Stepped away while I was typing and forgot to finish that sentence. My bad. :slight_smile:

Thanks for the response, Jon.

The LOGGER is not the only issue I’m seeing. It is a ton of injections that begin failing. The strange part is that system will operate fine, under load, for hours, days, etc., then all of a sudden, begin kicking out these errors. It is almost like the objects have been evicted from cache.

More to the point of your question, the LOGGER is injected into the variables scope (since it is used a LOT within a service), and thus does not have to (per my understanding) need to be scoped when called. Following is a segment of code that reflects specifically, an instance of the problem:

component
displayname=“model.sms.EngineService”
output=“false”
autowire=“true”
singleton=“true”
{

// Base Dependency injections
property name=“LOGGER” inject=“Logbox:logger:{this}” scope=“variables”;

// Engine sub-systems
property name=“ReportScanner” inject=“model:sms.ReportScanner” scope=“instance”;
property name=“InboxScanner” inject=“model:sms.InboxScanner” scope=“instance”;
property name=“QueueBuilder” inject=“model:sms.QueueBuilder” scope=“instance”;
property name=“DeviceSync” inject=“model:sms.DeviceSync” scope=“instance”;
property name=“Cleaner” inject=“model:sms.Cleaner” scope=“instance”;

public EngineService function init() {
return this;
}

public struct function process() {
var result = {};

// Retrieve requestContext collection
var rc = instance.controller.getRequestService().getContext().getCollection();

// ---------------------------------------------------
// Invoke the InboxScanner to process inbound messages
// ---------------------------------------------------
LOGGER.info(“Starting SMSEngine InboxScanner to processing incoming messages”);
try {

// Invoke InboxScanner process
var rsResult = instance.InboxScanner.process(rc.engineInfo);

// Add log entries and update stats
LOGGER.info(“SMSEngine InboxScanner completed. #rsResult.processedCount# inbound entries processed”);
SMSLog.addLogEntry(activityType = “Engine”, activityValue = “EngineStatus”,
argumentCollection = {
sessionId = rc.engineInfo.getSessionId(),
comment = “InboxScanner completed after processing #rsResult.processedCount# inbound entries”
});

// Update engine stats
rc.engineInfo.getStatistics().set( “reportsPublished”, rsResult.processedCount );
if( !rsResult.success ) {
rc.engineInfo.getStatistics().set( “errorFlag”, true );
}

} catch( Any e ) {
SMSLog.addLogEntry(activityType = “Engine”, activityValue = “EngineStatus”,
argumentCollection = {
sessionId = rc.engineInfo.getSessionId(),
comment = “InboxScanner returned error - #e.message#”,
errorInfo = serializeJSON(instance.UtilityService.trimErrorInfo(e, “model,handlers”))
});
LOGGER.info("SMSEngine InboxScanner returned error: #e.message# - #e.detail# " &
“(Session #rc.engineInfo.getSessionId()#”);
rc.engineInfo.getStatistics().set( “errorFlag”, true );
}

}

}

I’ve trimmed a lot of the code out, leaving the above only for demo purposes. 99% of the time, everything is fine, but when it goes wonky, it starts logging that all the sub-systems (injected) don’t exist, including the LOGGER.

Thanks for looking at this. I have checked for any circular dependency injection, and we don’t have any. Also, we are only using the simply dependency injection, not a custom wirebox configuration.

Cheers!

Kevin S. Anderson
Software Engineer
Intelligent Software Solutions Inc.