Some cool things in Lucee

This post is more than 2 years old.

I really haven't spoken much about Lucee since the initial announcement a few months back. It seems like a lot of "things" are going on, and frankly, I figured I'd just see where things settle down later this year. It just so happened that I ended up on the cfapplication doc for Lucee and I was pretty surprised by what I saw. Here are some of the cool things Lucee is doing with Applications versus ColdFusion. This probably isn't everything, but here is what I found and what I thought was cool or interesting.

By the way, just in case it isn't obvious - this list comes from the documentation for the cfapplication tag and is presented as arguments for the tag. Each of these works as "this" scope values in App.cfc too. That is implied, but it may not be obvious from the docs themselves.

action

So this falls into the "interesting but not sure I'd use it" bucket. Lucee provides an action attribute for applications that allow you to update settings for an existing application. Personally, changing application settings on the fly feels like a bad idea, but it feels like something that should exist and it is cool that it is supported. I'm sure folks will tell me plenty of reasons why this makes sense in the wild, and frankly, I don't really care, it jut makes me happy that it is supported. (Ok, I do care, and would love to hear some practical uses for this.)

sessionStorage

This one is cool as heck. You can use a database for session storage versus just plain RAM. You can setup the DSN in the admin enable this feature by checking the "Storage" checkbox:

Lucee_Server_Administrator

While I was writing this, I was curious how this would be done in App.cfc code instead. I just now discovered that the Lucee admin will actually tell you how to define your DSN in code. THAT IS EPIC.

shot2

One cool thing this allows for is ad hoc queries against the database for things like checking the number of active sessions or gathering up session data in general. That's doable now with the Server Monitoring API in ColdFusion, but that's Enterprise only and requires admin-level access. This would require a database query.

bufferOutput

I had to ask for help on this one - thanks go to Harry Klein and Gert Franz on the Lucee google group. I'm going to quote Gert here:

If there is an error or abort inside the function or the silent tag and the setting bufferoutput is set to true any generated output will bee visible. If set to false it will not generate any output at all.

Interesting. Apparently this helps in memory consumption. I don't see how - but I trust Gert and Harry.

requestTimeout

You know how you can set a request timeout value in the cfsetting tag? From what I see, this is the same thing, but for the application. Nice.

componentPaths

It looks as if Lucee supports mappings for cfinclude, custom tag paths for custom tags, and component paths for CFCs. This seems like a nice separation of concerns. I dig it.

typeChecking

Nice - you know how you can disable type checking in the ColdFusion Administrator? It can be a good performance boost. I've seen it significantly help out Model-Glue applications. Well this is the same thing - but at the Application level.

compression

This allows you to enable GZip compression for the application. I kinda feel like this should be done on the web server and not the app server, but meh, it works well and is incredibly easy to enable. Here is a page with the setting turned off:

shot3

I then added this.compression=true; to my App.cfc:

shot4a

That's a pretty big change there.

suppressRemoteComponentContent

So yeah, this is a weird one. Imagine bad code like this:

remote function sayhello() {
	writeoutput("MOO");
	return "hello #now()#";
}

As you can see, I'm both outputting stuff and returning a value. If you set the suppress setting to false, you will actually see "MOO" in the remote output. I see no reason why you would ever desire that.

localmode

This one was pretty confusing. @nicholasc on Slack helped me understand it. Given this line in a method x=1;, by default this will write to the variables scope unless local.x was already set. If you use this.localmode="modern" in your App.cfc, it will set to the local scope instead. This seems like a great idea.

tag

My favorite change. You can specify default attribute/value pairs for tags across your application. Here is an example I took from the docs:

this.tag = {
	"location":{
		"addtoken":true
	}
};

I freaking love this. I kinda remember arguing against this in ColdFusion about 5 or so versions ago. At the time I was concerned about some setting somewhere modifying code and developers getting confused, but having it in app.cfc makes it easy to reference and notice.

locale/timezone/webcharset/resourcecharset

These all apply different language/locale type settings to your application.

scopeCascading

Ok, I lied - this is my favorite feature. If you output a variable without scope, this defines the "look" up process. You have three values. "standard" is your standard lookup table and will hit variables, CFI, URL, Form, and Cookie. "small" will hit just variables, URL, and Form. My favorite though is "strict". If you specify this, it will only look at the Variables scope. My own personal rules are to always scope for everything but Variables so I definitely approve of this change.

And more...

There's some cool cache settings you can tweak and CFC property stuff, but they weren't interesting enough for me to actually write up.

But...

Yeah... this is what I like. This is exactly the type of developer-centric language changes I'd like to see in ColdFusion 12.

At this point, someone may chime in and suggest I file ERs in the Adobe bug tracker. I certainly could - but I assume the Adobe ColdFusion team naturally tracks what Lucee is doing. It just makes sense. Surely they watch Lucee, look at developers who get excited about it, and take note of that. To assume otherwise would be to assume a ColdFusion team that is so disconnected from the developer community that it thinks it doesn't matter what other CFML engines do. And surely that can't be the case.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Brad Wood posted on 10/2/2015 at 3:12 AM

Great list, Ray. I've taken a lot of this for granted, but I'd actually like to submit a "hidden gems in Lucee" kind of talk aimed a exposing some of these cool features.

> I assume the Adobe ColdFusion team naturally tracks what Lucee is doing.

I asked several of the engineers and product management about this (Railo at the time) at the last CF Summit and they had never looked at or used it. I know I have personally introduce many Railo/Lucee features over the years to the CF team.

> You can use a database for session storage versus just plain RAM

One of my favorite Lucee features is the ability to define any number external cache providers that even use Lucee Extensions to connect to, say, Couchbase. That REALLY makes the "sessionStorage" option come alive for true scaling since it can also point to a cache. Just remember to set sessionCluster to true if you have more than on web server in the mix.

> Ok, I do care, and would love to hear some practical uses for this.

Regarding the "action" attribute for cfapplication-- ColdBox uses this to add application-specific mappings on-the-fly when modules are loaded which is a HUGE thing for self-contained modules that need CFC paths. Case in point: imagine you want to write a module for the ColdBox framework that defines an interface or base component that the developer (or another module) will want to implement/extend. Modules can be installed anywhere-- the /modules convention, an overridden folder, the core /coldbox/modules folder, or even as a nested module inside a parent module (a-la Node module dependency). What the heck will the full CFC path be to this self contained-module at run time? Let's say the module is called "foo". Coldbox adds "/foo" as an app mapping (via cfapplication's action=update) and points it to the folder where the module was installed. Boom. foo.baseClass is now the path no matter where the module was installed to. That's my use case anyway. Note, adding app mappings on the fly works on Adobe CF, but while officially "supported" (by our request) in CF11, it's not nearly as well done.

Comment 2 by Julian Halliwell posted on 10/2/2015 at 8:26 AM

Really useful post, Raymond.

bufferOutput=false helps with speed and memory consumption I think because, instead of buffering and then suppressing the output inside <cfsilent> and <cffunction output="false">, Lucee just doesn't buffer the output in the first place. So it's doing less work and using up less temporary memory..

The downside is that if an error occurs within one of those tags, you'll get a blank page instead of being shown the exception. Not what you want when developing locally, but because it can be set in App.cfc you can simply switch it on or off according to your environment.

The same applies to this.typeChecking=false;. Have it on in dev, but turn off in production for a performance boost.

Comment 3 (In reply to #1) by Raymond Camden posted on 10/2/2015 at 1:22 PM

Cool, thanks for the example.

I'm disappointed but entirely not surprised that the Adobe CF team doesn't check Lucee/Railo. Maybe there is some legal reason (if Lucee adds X and we do we can be sued).

Comment 4 by Pete Freitag posted on 10/2/2015 at 4:57 PM

Nice summary Ray, I didn't know about the "tag" option, that is pretty cool.

I will caution that the compression setting can be problematic, and is probably best handled by the web server instead. I've seen a few issues that were resolved by turning it off in the past.

Comment 5 (In reply to #4) by Raymond Camden posted on 10/2/2015 at 6:16 PM

That matches what my gut was saying.

Comment 6 (In reply to #2) by Gert Franz posted on 10/5/2015 at 6:50 AM

Hey Julian,
that is not quite accurate. Errors will still be thrown when you have the attribute set. It is just that the content generated inside those tags will not be available for output.

Due to the fact that in 99% of the cases a CFSilent is doing what a CFSilent is supposed to do, which is to prevent any output, the setting makes a lot of sense, since generating the output (buffering it) consumes memory. This used memory then has to be removed some time by the garbage collector. This obviously uses way more memory and occupies
the CPU more than with the setting set to true.

Comment 7 by Gert Franz posted on 10/5/2015 at 6:59 AM

>> Ok, I do care, and would love to hear some practical uses for this.

We have an application with a client where many settings (like the framework version, datasources others.) are stored in a database or other storage. When the application has loaded the settings from the one single datasource which holds all the configuration data, the rest will be injected into the application with the tag <cfapplication action="update" ...="">

Just as a BTW. The tag cfapplication can do (I guess everything) what the settings for the Application.cfc are offering.

localmode

The local mode is something that IMHO should have been set for ACF since DAY 1. Unscoped variables should be stored in the local scope by default. This setting is a general setting and affects the application completely for every function or method. The attribute "localmode" is also available for the tag function AND for the tag component. So you can set it per component or per function individually. Just imagine a CFC having concurrency issues. Setting the localmode="true" attribute on top of the component immediately helps fix the issue.

Regarding cloning Lucee features

THERE IS NO REASON why Adobe cannot clone or copy stuff from Lucee. They have done it in the past (even though sometimes a tiny bit different) and I encourage them to do it in the future too. Lucee is LGPL V2 open source. Best thing to do for CF12 would be git clone lucee :)

Comment 8 (In reply to #6) by Julian Halliwell posted on 10/5/2015 at 7:00 AM

Thanks for the correction, Gert. Having turned this on, I was indeed getting a blank page when an exception was thrown. But I've since realised that's because my error handler is rather old and was using <cffunction> tags. So bufferOutput=false was just doing its job. When I changed it to script, the errors where output again.

Comment 9 (In reply to #4) by Gert Franz posted on 10/5/2015 at 7:04 AM

I agree that this is not something you should set, if you have a web server in front. But if you don't it is helpful. In the past there were some issues with the tag CFFLUSH and some others like whitespace supression which were caused by this setting. But AFAIK they have been fixed.

Comment 10 (In reply to #7) by Raymond Camden posted on 10/5/2015 at 10:23 AM

Thanks for the comment - some good stuff here!

Comment 11 by itisdesign posted on 10/10/2015 at 7:55 AM

Hi Ray,

Regarding THIS.tag, I *really* want that in CF12. I filed a ticket during CF8 for the basic idea: https://bugbase.adobe.com/i...

Thanks!,
-Aaron

Comment 12 by Bruce Van Horn posted on 1/28/2016 at 9:07 PM

Ray, do you know of anyone using Lucee in a production environment?

Comment 13 (In reply to #12) by Brad Wood posted on 1/28/2016 at 9:34 PM

Bruce, there are a large amount companies using Lucee in production. even big names like NASA. The recent State of the CF Union survey shows 34% of all respondents are using Lucee 4.x and 16% are already using Lucee 5 beta.
https://www.surveymonkey.co...
If you jump in the Lucee Google Group or #lucee channel of the CFML Slack team, I'm sure you'll find many people willing to give you more specifics.

Comment 14 (In reply to #13) by Bruce Van Horn posted on 1/28/2016 at 10:03 PM

Brad, this is very helpful. Thank you!!

Comment 15 (In reply to #13) by Raymond Camden posted on 1/29/2016 at 12:03 AM

Thanks for answering his question, Brad!

Comment 16 (In reply to #12) by dawesi posted on 4/16/2016 at 2:48 PM

I'm using it for a white label event ticketing company (think Eventbrite, but with useful features)

Comment 17 by Andrew Wilson posted on 8/30/2016 at 2:43 PM

Where is the "Storage" checkbox situated in the Lucee Administrator? We can't seem to find it. Or is it only on particular versions of Lucee?

Comment 18 (In reply to #17) by Raymond Camden posted on 8/30/2016 at 3:18 PM

In Lucee 5, it is Settings - Scope.

Comment 19 (In reply to #4) by dawesi posted on 2/3/2017 at 6:10 AM

does is compress then compile, aka compress before the bytecode?

that would make it a feature to bypass the server compression if it did... bytecode would be heaps faster than runtime compress on web server...

Comment 20 (In reply to #19) by Pete Freitag posted on 2/3/2017 at 1:45 PM

I don't think it would be possible to do the compression at compile time because it would not have all your runtime variable values.

Comment 21 (In reply to #7) by Ben Nadel posted on 8/8/2019 at 10:04 AM

Re: localmode, oh cool, I didn't realize you could set it on a per-component level as well! I haven't played around with it yet; but, this make it feel easier to roll-out to a brown-field application.

Comment 22 (In reply to #21) by Ben Nadel posted on 8/8/2019 at 10:16 AM

Actually, I just tried it on the component tag and it does not appear to work...

Comment 23 (In reply to #22) by Gert Franz posted on 8/8/2019 at 10:44 AM

Actually it has to work. If it doesn't it's a bug. But you can definitely do it on application level. The admin section gives you the hint for that code for Application.cfc (I forgot :))