by Andrew Dixon, Technical Director at MSO
Introduction
Whilst Lucee is generally compatible with Adobe ColdFusion (ACF) and the vast majority of your ACF code will run on Lucee “out of the box” it is worth noting that there are some differences.
During its design and implementation, some differences have been introduced to either give Lucee a performance advantage or just to generally improve on the ACF implementation. Also, some features of ACF have deliberately been left out of Lucee, either because they are proprietary technology owned by Adobe or the Lucee team believe they serve little to no value and therefore should not be included.
Migration Starting Point
A good place to start a migration from ACF to Lucee, particularly for someone who knows their codebase well, is to look at the list of unsupported tags and functions. These are the tags and functions that have not been implemented in Lucee. The list can be found here:
After reviewing this, if you see any tags and/or functions that you know are used in your codebase, you will need to look into how you can change your code to do the same job in a different way or to change how that part of your system works altogether.
There are, however, a couple of exceptions to this. and its associated functions have been implemented by a free, open-source, 3rd party plugin by Andrew Kretzer and can be found both in the Lucee Admin > Extension > Application section and installed with a couple of clicks and on Github here:
Also, WebSockets, have been implemented as a plugin by Lucee Core contributor Igal Sapir and can also be installed via the Lucee Admin > Extension > Application section as well as via Github here:
There is, however, no compatibility between ACF’s WebSockets implementation and this plugin, but it will make it possible for your app to operate with WebSockets if that is required.
Next Step
Lucee contains a mapping feature that allows you to create a virtual mapping from an actual location, and along with this feature is an option to “compile” the code. This feature allows you to have Lucee essentially scan your code and find anything that might not work with Lucee, for example, tags and functions that have not been implemented.
To do this, once you have a Lucee server up and running and have set it up to serve your application, simply go to the Lucee Web Admin for the site and go to the Archives & Resources > Mappings section and to the “Create new mapping” section and create a mapping that points to itself, like this:
Then click “Save” and your new mapping will appear in the section above, that lists all the existing mappings.
Click the pencil icon to the far right of the mapping you just created and this will show you the edit mapping screen for that mapping. Locate the “compile” section and deselect the “Stop on error“ option:
Then click the “compile” button. This will then start Lucee off compiling your code, which depending on the size of your codebase, might take some time. Once it has completed, if there are any issues, these will be listed, in red, at the top of the page, like this:
This gives you some items to work through and fix before proceeding further.
Further Considerations
There are a few more things to consider in the differences between Lucee and ACF that might affect how your apps behave when running on Lucee and need to be considered.
Arrays Passed by Reference
In Lucee arrays are passed to functions by reference meaning that any changes made to that array inside of the function are reflected in the original array passed in, however, in ACF, arrays are passed by value, meaning that a new copy of the array is used and changes made inside the function are not reflected in the original array.
Let’s consider the following simple example:
In Lucee this code will produce the following output:
However, in ACF you will get this output:
There are two main reasons for this difference. Firstly, passing arrays by reference is consistent with all over complex value types and secondly, creating a copy of an array on each and every function call creates a lot of overhead and can have a serious impact on performance.
Hash Iterations
The hash() function takes a parameter called “iterations” which is the number of times to iterate the hash, however, in ACF this parameter is actually the number of additional iterations to do and not the number of actual iterations to do, so ACF always does one more iteration than the number specified, however, Lucee does the number of iterations requested. Therefore, if you have used this function in your code on ACF and require the same result on Lucee you will need to increase your iterations by one, for example:
Hash(“somestring”, “SHA-512”, “utf-8”, 100); // in ACF
Hash(“somestring”, “SHA-512”, “utf-8”, 101); // Lucee
Both of these will produce the same result when executed on the appropriate system.
Other Issues
There are also some functions where Lucee has a slightly different implementation to ACF, for example in ACF the cacheGetMetaData() function has three possible arguments but in Lucee it only has two, with Lucee not supporting the “region” argument. Most of these will become obvious as you run your code on Lucee and just require minor adjustments to fix.
Conclusion
Whilst this looks like a lot, Lucee is generally very compatible with ACF and for most applications, there is often very little that needs changing or fixing. Lucee is, on the whole, faster, cheaper to run and has no licensing headaches to deal with, as it is free open-source software. The Lucee community is very helpful and with its open and transparent setup, everything is available for everyone to see, in the open.
Discussion of the Lucee project occurs here:
The issue and bug tracker can be found here:
https://luceeserver.atlassian.net/secure/Dashboard.jspa
And there is “realtime” discussion in the Lucee channel on the CFML Slack, which you can join via this link: