Using CFCProxy inside CF to call a CFC via file path

Friday, March 21, 2008

One of the main goals with MXUnit is that you can download it and run it from any location accessible by ColdFusion with as little configuration as possible - hopefully none at all. The main issue is that we needed a way to determine where MXUnit is installed in the target environment. Starting in CF6 you can get a wealth of information about a CFC by invoking getMetaData(theCfc). The problem is you need to specify a reference to that component as the server sees it; i.e., We know our product well and it's structure is stable. The idea of using the meta data from the MXunit installation seems logical, but in order to do this we need to use a relative path to a known CFC, instantiate that, get its meta data, and infer where MXUnit is installed. Enter CFCProxy ... This is a java class that was apparently shipped with CFMX 7 updater 1?, but the only documentation *I* found was at Ben Forta's site: It looks like the intention of this was aimed at providing the ability of servlets and other Java classes to collaborate with CFCs. And as we now know, it's quite simple to instantiate java classes inside CF and execute their methods. With CFCProxy, the constructor accepts a file path to the CFC and returns a proxy object. This proxy object is used to to call methods on the CFC. This is how it works : <cfscript> // @pre path to framework/ComponentUtils is static //the pwd context = getDirectoryFromPath(getCurrentTemplatePath()); //init() calls the constructor that accepts the path to a cfc proxy = CreateObject("java", "coldfusion.cfc.CFCProxy").init("#context#framework/ComponentUtils.cfc"); //if your page prints anything, make sure you tell the proxy not to do any writes proxy.setAutoFlush(false); //proxy.invoke() expects an array of objects ... Object[] args = arrayNew(1); //the proxy returns a reference to the CFC as a struct componentUtils = structNew(); //instantiating the component ... ComponentUtils is *our* contstructor that //returns an instance of the cfc. componentUtils = proxy.invoke("ComponentUtils",args); //Now that we have an instance, we can get at it's meta data componentUtilsName = getMetaData(componentUtils).name; //We also use this object to infer path information componentRoot = componentUtils.getComponentRoot(componentUtilsName); ... </cfscript> For details on getInstallRoot() and getComponentRoot(), download MXunit and browse to mxunit/framewor/ComponentUtils.cfc. Special thanks to Adam Haskel for the J2EE information on getPageContext().getRequest().getContextPath()! -bill

No comments: