CommandBox 5.5 and injecting models into Task Runners

CommandBox 5.5 has a lot of new features, but there are just as many bug fixes and improvements. Sometimes these tickets unintentionally change some internal behavior you may have been depending on, but was never guaranteed.

One such change that caught a couple people out was that the underlying “web root” that Lucee uses under the covers changed from the folder box.exe was started in to the root of your drive (C:/ or / in *nix). This was done for a handful of reasons, one of which being a super annoying Lucee bug where it’s literally impossible to create a CF mapping that points to / on Linux.

None the less, there were some users making use of that behavior in their task runners. They had a file system like so:

- task.cfc
- mymodel.cfc
- models/
  - anotherModel.cfc

Inside their task.cfc they would inject the models like this:

component {
  property name="myModel" inject="myModel";
  property name="anotherModel" inject="models.anotherModel";

  function run() {
    myModel.doSomething();
    anotherModel.doSomething();
  }
}

This makes use of a lesser-known feature of WireBox where, being unable to locate an instance mapping with that name, will look for a CFC using CF’s built in resolution of createObject() which relies on your CF mappings-- namely the / mapping that points to Lucee’s “web root”. Note, a CLI tool doesn’t really have a “web root”, but Lucee still has one under the covers.

Starting in CommandBox 5.5., that same Task Runner would now throw the following error since it could no longer find the injections based on Lucee’s / mapping.

The target 'task-...' requested a missing dependency with a Name of 'myModel' and DSL of 'myModel'

Now, I don’t recommend using this more ambiguous method to inject models-- if you want to know what I do recommend, check the link at the bottom of this post.

To provide some backwards compatibility, I have written a simple CommandBox module that taps into WireBox’s beforeInstanceAutowire interception point and inspects the Task Runners property injections, applying a “fix” to any of them pointing to a file in the shell’s current working directory.

If you happened to depend on that behavior in older versions of CommandBox, you can install the module like so:

install commandbox-task-local-model-resolver

But even if you didn’t depend on that behavior, you can still check out the code which is only about 15 lines and very simple. Interceptors are a very powerful mechanism to modify the behavior of CommandBox/WireBox/etc on the fly!

And if you’d like some more advice on how I recommend loading CFCs from inside of Task Runners, read this: