This is a follow-up to my previous post, Tips for Moving From ColdFusion to Lucee. I found these additional issues/differences when converting a major enterprise environment containing 15+ years of legacy code and over 200 applications. Most of these are due to poor programming practices, but I want to note them here because they are differences (incompatibilities?) that need to be addressed if you are moving code from Adobe ColdFusion to Lucee.
1. Unscoped Variables named “url”
<cfquery name="getData" datasource="mydsn"> SELECT title,url FROM site_links </cfquery> <cfoutput query="getData"> <a href="#url#">#title#</a> </cfoutput>
This code will throw an exception in Lucee because the variable #url# is a struct in Lucee. Adobe CF will look at the query scope ahead of the URL scope and will not throw an error.
To fix your code for Lucee, you simply need to scope the query variables (as should have been done to begin with).
<cfoutput query="getData"> <a href="#getData.url#">#getData.title#</a> </cfoutput>
2. Invalid cfsqltype in <cfqueryparam>
I found several instances where developers accidentally misspelled the cfsqltype, or specified one that doesn’t exist. ACF and Lucee handle these errors differently.
<cfqueryparam name="thisval" value="" cfsqltype="CF_SQL_INTGR" />
Lucee throws an error because it is an invalid cfsqltype. ACF allows it to pass, but makes it a CF_SQL_VARCHAR type.
3. Param type=”variablename” Difference
This is a bit of an odd one. There was a developer who was using <cfargument type=”variablename” name=”filename” /> with any file that was uploaded. This was an attempt to prevent file uploads with malicious or complex names I believe.
ACF would allow a period in the argument. For example, “myfile.pdf” was a valid value.
Lucee throws an error because a variable name should not contain a period.
It’s obviously an improper use of the variablename type. However, there is a difference in how the two agents handle the situation.
4. CFDOCUMENT PDF Formatting
This was the single biggest time drain in this large project. ACF and Lucee use different rendering engines for PDFs. They can be significantly different in how the PDF displays. The biggest problem is the default document width, which is much smaller in Lucee and therefore makes it appear as if the fonts are huge. This also messes with the alignment of pages.
I found that if I put an outer DIV with a width of 700px around the content, it gets me somewhat close in terms of width and where pages break.
There are also many other differences between how the engines render the PDF, probably too many to mention here.
Some tips…
- Do not float <span> tags. If you have a label or text that needs to float left, change it to a DIV
- Put inline CSS for the PDF at the bottom of the code block if you are using <cfdocumentsection> or <cfdocumentitem> for headers, footers, etc.
- Table cell borders are somewhat of a mystery in terms of when they display in Lucee and when they don’t. I had some situations that required an inline style on the element.
5. Query of Queries, SELECT DISTINCT and ORDER BY
<cfquery name="getDistSorted" dbtype="query"> SELECT DISTINCT name FROM myquery ORDER BY price,name </cfquery>
This appears to work in ACF, but Lucee throws an error saying that the ORDER BY column “price” needs to be in the list of DISTINCT columns. It can be added for Lucee, and the query results are the same.
6. JavaCast with Java Objects
Lucee is much more strict when it comes to data types being passed into Java objects.
<cfscript> var javaObj = createObject("java","path.to.class"); var mystring = "my string"; javaObj.doSomething(mystring); </cfscript>
This works fairly consistently in ACF, but is less consistent on Lucee. I suspect it’s something to do with the way that Java class itself is programmed, but this code works more consistently and works well in both engines.
javaObj.doSomething(JavaCast("string",mystring));
7. CFIMAP does not support subfolders, and has different syntax
I had a lot of trouble with the implementation of <cfimap> that is in Lucee. It seems very incomplete. The “connection” attribute doesn’t seem to work. Also, reading a list of messages from a subfolder does not work. I will admit that I didn’t spend a lot of time on this, and did not get enough information for a bug report. Instead, I switched to using the lucee-cfimap library from Tropicalista. This gave me a more complete set of features, although it also had a few issues. I submitted pull requests to correct the issues but they have not yet been accepted as of the writing of this article. See the pull requests if you want replicate what I did.
8. cflocation url=”?” causes a redirect error
The developers often used a <cflocation url=”?” /> to return to the home screen of an application after an action is completed. With Lucee on IIS/Windows2008, this throws an error through IIS. You can put anything after the question mark and it will work. For example, <cflocation url=”?home” />.
9. Cannot have a closing cfinput tag (</cfinput>)
Odd, but there were several instances of a closing <cfinput> tag in this code base. <cfinput name=”name”></cfinput> for example. This was not a problem in ACF, but throws an error in Lucee.
10. Validate=”submitonce”
This is probably documented in the Lucee notes, but this feature is missing from Lucee. You have to prevent duplicate form submissions with your own JavaScript.
Next Steps
For the purposes of anyone submitting comments, I numbered the issues above. Also, I plan to submit bug reports or feature requests to Lucee for items 1, 2, 8, and 10. The others are more informational for anyone making the migration from Adobe ColdFusion to Lucee.
One Reply to “Tips for Moving From ColdFusion to Lucee, Part 2”