NullPointerExceptions in ColdFusion 9 and ColdBox

2019-07-24 04:32发布

问题:

I'm running CF 9.0.1 Developer and Coldbox 3.0.0 on my local machine (64-bit Windows Vista running 32-bit CF9 on Apache). I'm working on an application that I've checked out from SVN and deployed locally. Everything seems to be working correctly, but my application log is filling up with entries like this:

Apr 18, 2011    12:41 PM    Error       jrpp-7   

exception.log has an extremely long stack trace for each exception, maybe 150 lines or so. It starts with this:

"Error","jrpp-4","04/18/11","11:07:30",,""
java.lang.NullPointerException
    at coldfusion.util.Utils.getServletPath(Utils.java:86)
    at coldfusion.util.Utils.getServletPath(Utils.java:76)
    at coldfusion.util.Utils.getBaseTemplatePath(Utils.java:405)
    at coldfusion.runtime.TemplateProxyFactory.getTemplateFileHelper
        (TemplateProxyFactory.java:1522)
    at coldfusion.runtime.MetadataUtils.getComponentMetadata
        (MetadataUtils.java:112)
    at coldfusion.runtime.CfJspPage.GetComponentMetaData(CfJspPage.java:2667)
    at coldfusion.runtime.TemplateProxy.getRuntimeComponentMetadata
        (TemplateProxy.java:1756)
    at coldfusion.runtime.TemplateProxy.getRuntimeMetadata
        (TemplateProxy.java:1617)
    at coldfusion.runtime.MetadataUtils.getMetaData(MetadataUtils.java:54)
    at coldfusion.runtime.CfJspPage.GetMetaData(CfJspPage.java:2640)
    at cfEventHandler2ecfc862260423$funcPOSTLOAD.runFunction
        (C:\ColdFusion9\wwwroot\ybocv5\coldbox\system\orm\hibernate
            \EventHandler.cfc:30) 

This is a version of an app that has been running in production, and what makes me think this is just on my local version is the appearance of this in the stack trace:

at cfdump2ecfm471394032$funcRENDEROUTPUT.runFunction
    (E:\cf9_updates_rc\cfusion\wwwroot\WEB-INF\cftags\dump.cfm:704) 
...
at cfCollectionPanel2ecfm961210602.runPage
    (C:\ColdFusion9\wwwroot\ybocv5\coldbox\system\includes
        \panels\CollectionPanel.cfm:40) 

We don't use cfdump in production; this looks like ColdBox is trying to display a complex object in a debugger panel and failing.

The only thing I found online so far was this thread in Google's transfer-dev group ... someone who saw a bunch of similar errors and thought maybe it was a CF9 bug. The only reply with any sort of solution was this one, suggesting a fix that seems to be Transfer-specific.

Does anyone know what might be causing these errors? It's not as important to me to fix them as it would be on a production app, but if I'm spamming my logs with these errors, it's hard to find legitimate errors when they do occur.

Update: I've been working with the CollectionPanel.cfm template to identify the root cause, and the exception is consistently thrown here:

    <cfelseif isObject(varVal)>
        <!--- this cfdump is the guilty party ... --->
        <cfdump var="#varVal#" expand="false" top="2">
    <cfelse>

I've tried wrapping the cfdump in a try-catch, but the exception is thrown anyway, always from that same line of code. This makes sense, I guess, given that these errors don't have any visible effect on the pages on which they occur.

回答1:

It appears to not be caused from a <cfdump> instead from a GetMetaData() call. Specifically when you get the meta data of a cfc, which extends another cfc which has been modified after the current has been compiled (and where GetMetaData has been run) where it needs to update the extends struct in the GetMetaData() return. Cf only generates the meta data struct once, most likely for performance reasons.

I think it might be a bug in cf...

Inside the TemplateProxyFactory.getTemplateFileHelper() it's calling runtime.resolveTemplatePath(compName + ".cfc") where compName is name.replace('.', '/')

All good and well until you use a mapping. If you straight out replace dots with slashes, you'll need to add a leading slash, just like they do in TemplateProxy.getMetaData()

Without the leading slash, resolveTemplatePath() returns null, which triggers the VFSFileFactory.getFileObject() call which tries to get a File object from the parent cfc name.

Before it even gets to the VFSFileFactory, it calls Util.getBaseTemplatePath() with the pageContext. Inside it gets the ServletContext from the pageContext and tries to call getServletPath() so that it can get its real path. Utils.getServletPath() tries to get the attribute "javax.servlet.include.servlet_path" which on my machine (and probably yours) doesn't exist and returns null.

You can check by calling this: isNull(getPageContext().getRequest().getRequest().getAttribute("javax.servlet.include.servlet_path")); - yes, there is supposed to be two .getRequest() calls in there.

So it seems Cf is trying to refresh it's extends struct in a cfc getMetaData() call when the extended file is modified and does it a different way then when it first generated the struct.

In you cf admin, what are you settings under Server Settings > Caching? Trusted cache? Cache template in request? Component cache? Save class files? Cache web server paths?