Compile CFML to Java Bytecode plus Fusebox Fix

Published: {ts '2010-11-06 00:00:00'}
Author: Steven Neiland
Site Url: http://www.neiland.net/article/compile-cfml-to-java-bytecode-plus-fusebox-fix/

Its not mentioned often but while most people run normal cfml on their sites, it is actually possible to precompile the cfml into java bytecode and run that. At this point you are asking why would I want to do that.

Improve Performance

By compiling to javabyte code you save coldfusion from having to compile the source code the first time that page is loaded. This improves performance especially if you have a large number of templates and restart you server.

Protect IP

Secondly by deploying java bytecode instead of plain text cfml you can protect my intellectual property. This can be quite important as a contract term, for example you might specify that source code is only turned over on final payment. Or maybe someone has licenced the use of a component and you want to make it harder for it to be passed on etc.

Introducing the Compiler

Adobe makes precompiling our source code easy with a handly utility in the coldfusion bin directory called cfcompile.bat . This file is located at {coldfusion-install-dir}\bin\cfcompile.bat .

To run this file open a cmd prompt window, navigate to the directory where cfcompile.bat is located and run the following command.

cfcompile -deploy [webroot] [sitedir] [outputdir]

For example say you have a webroot folder at c:\htdocs with a site named myblog located inside the webroot at c:\htdocs\myblog and you want to compile this code to an output directory of c:\htdocs\myblogcompiled . You would run the following command.

cfcompile -deploy c:\htdocs c:\htdocs\myblog c:\htdocs\myblog\compiled

Note that I do NOT put quotes around the directory paths.

Problems with Fusebox 4+

At this stage you should be able to deploy your compiled code and enjoy the benefits of precompiled cfml...that is unless you happen to use the fusebox framework (specifically the xml based versions 4 and above).

The problem is that fusebox4+ uses xml config files. In of itself this is not a problem except that it is necessary to hide these files from being directly visible. Fusebox accomplishes this by appending the cfm extension to the xml config files. Thus a circuit.xml file is actually named circuit.xml.cfm . This results in the cfcompiler trying to translate the xml files into java bytecode. While the compiler succeeds Fusebox is unable to read and utilise the resulting gibberish.

The Batch File Solution

Fortunately the solution is a little piece of batch file magic. First create a txt file and paste the following code.

@echo off echo Please input source folder path (DO NOT QUOTE PATH) echo Wrong: "C:\DIR\FILES\" echo Correct: C:\DIR\FILES set /p source=Source Directory: echo Please input destination folder path set /p dest=Destination Directory: :: /s tells xcopy to also do subfolders :: /y turns off overwrite prompt xcopy /s /y "%source%\*.appinit.cfm" %dest% xcopy /s /y "%source%\*.init.cfm" %dest% xcopy /s /y "%source%\*.xml.cfm" %dest% echo Files successfully copied! pause>nul exit

Now convert the txt file to a batch file by changing its extension from.txt to .bat. Name this file as "fuseboxCompileFix.bat". After creating our java bytecode we can run fuseboxCompileFIx from the command prompt to go back to our source code directory and recopy the xml config files to overwrite the bytecode gibberish in the compiled directory.

All this code does is ask for the source code directory, the destination (ie compiled code) directory and recursively overwrite any of the three types of config file with the source code original.

Hook into cfcompile

As a final improvement you can modify the cfcompile.bat file to do this itself and do away with the seperate batch file altogether. Open the cfcompile.bat for editing and search for the following line of code.

:afterdeploycompdir %JAVACMD% -cp "%J2EEJAR%;%WEBINF%\lib\cfmx_bootstrap.jar;%WEBINF%\lib\cfx.jar" -Dcoldfusion.classPath=%CFUSION_HOME%/lib/updates,%CFUSION_HOME%/lib -Dcoldfusion.libPath=%CFUSION_HOME%/lib coldfusion.tools.CommandLineInvoker Compiler -webinf %WEBINF% -webroot %webroot% -cfroot %CFUSION_HOME% -d -srcdir %srcdir% -deploydir %deploydir%

Immediately afterwards append the following lines and save. Now the cfcompile file will recopy our xml.cfm files to deployment in their original form. You can now delete the fuseboxCompileFIx.bat file.

::Added by steven to handle fusebox config xml files echo Recopying fuseboxconfig.xml.cfm files to deployment directory xcopy /s /y "%srcdir%\*.appinit.cfm" %deploydir% xcopy /s /y "%srcdir%\*.init.cfm" %deploydir% xcopy /s /y "%srcdir%\*.xml.cfm" %deploydir%

And there you have it, precompiled cfml code in the fusebox framework. Enjoy!