Forcing Lucee to re-check the physical paths of application defined mappings without a restart

15 October 2020

This post is a follow up to one of Ben's from almost a year ago in which he described Confusion Over this.mappings And expandPath() Not Working In Lucee.

What it boils down to is, as Ben says:

...the evaluation of the this.mappings paths gets "confused" ... if you attempt to reference a directory that does not yet exist

Take the following mapping defined in Application.cfc


this.mappings = {
  "/test": "c:\abovewebroot\test"
};

When the application first runs, if the path "c:\abovewebroot\test" doesn't yet exist, Lucee won't throw an error but will instead resolve the "/test" mapping to a path below the web root, for example "c:\abovewebroot\www\test". This is the "confusion" Ben is talking about.

Fine, you might think, I'll just create the physical folder and all will be well.

Unfortunately not. Once evaluated, Lucee will cache that incorrect path value for the life of the server. In other words, the only way of getting the physical folder "picked up" again is to restart the engine.

Edge case?

As Ben says this isn't likely to be a common situation. For the most part you'd expect mapped paths to exist each time you fire up an application. But we recently bumped into it when migrating some applications to a new physical server. One particular mapping pointed to a dynamically named backup folder which wasn't created until a particular scheduled task had run for the first time on that machine.

Lucee therefore resolved the mapping to an incorrect path below the web root and any ExpandPath() references continued to fail even after the task had run.

Restarting the engine fixed the issue, but it would have been much better to have been able to clear the cache (wherever that might be) or otherwise force Lucee to re-evaluate the path once it had been created, without the disruption of restarting a production server.

Unsupported workaround

I've raised a ticket for an official solution to the problem, but in the meantime I've discovered a "back-door" method which seems to be an effective way of forcing all of the current application's mappings to be instantly re-evaluated. Here it is wrapped as a one-line UDF.


void function recheckApplicationMappings(){
  for( var mapping in GetPageContext().getConfig().getApplicationMapping() ) mapping.check();
}

Posted on . Updated

Comments

  • Formatting comments: See this list of formatting tags you can use in your comments.
  • Want to paste code? Enclose within <pre><code> tags for syntax higlighting and better formatting and if possible use script. If your code includes "self-closing" tags, such as <cfargument>, you must add an explicit closing tag, otherwise it is likely to be mangled by the Disqus parser.
Back to the top