Skip to content

Using the Application.cfc Bootstrapper

thofrey edited this page Apr 1, 2014 · 13 revisions

Table of Contents

  1. What is a bootstrapper?
  2. Which bootstrapper (e.g. Application.cfm/cfc) should I use?
  3. The mach-ii.cfc bootstrapper
  4. The Bootstrapper Deconstructed
  5. Available Bootstrapper Methods
  6. Common Errors
  7. Additional Information

What is a bootstrapper?

By definition,a bootstrapper is a small and low level process that has a focused and singular task of loading a larger and usually more complex application. Typically we know the term of bootstrapping as booting. This occurs when you turn on a computer, a bootstrapper program is loaded and executed from ROM on power-up. In Mach-II, we use a bootstrapper that is invoked by your CFML engine to load and configure a Mach-II application for use. The lowest level in the terms of a CFML application would be the Application.cfc which is the hub of every client request to a CFML application. This the point in where you utilize the Mach-II bootstrapper.

Some the features in the Mach-II bootstrapper were added as enhancements in Mach-II 1.6. These enhancement were developed under the Mach-II specification and feedback process (M2SFP). For information on the evolution of these enhancements, please read the original Application.cfc Enhancements and onSessionStart/End Integration specification.

Which bootstrapper (e.g. Application.cfm/cfc) should I use?

Mach-II ships with two bootstrappers. The MachII.mach-ii bootstrapper is for use with Application.cfc (recommended) and a /MachII/mach-ii.cfm for use with Application.cfm (deprecated).

Bootstrapper Type Recommended Method Compatibile ColdFusion Engines** Description
Application.cfc yes
  • ColdFusion MX7
  • ColdFusion 8
  • BlueDragon 7+
  • Open BlueDragon 1+
This bootstrapper involves editing Application.cfc by extending this component.  The Application.cfc bootstrapper has been available since version 1.1.1.  Bootstrapping Mach-II with this method involves editing two files: mach-ii.xml and Application.cfc.  Typically, index.cfm serves as the central request hub, but need not have any code in it.  Whatever the default CFM file is for the web server could act as the central hub.
Application.cfm and index.cfm ("Classic" version") No; only use on ColdFusion engines that do not support Application.cfc, or in a mixed framework environment
  • ColdFusion MX 6.1
  • BlueDragon 6.2
The classic bootstrapper is required on installations on ColdFusion MX 6.1 and BlueDragon 6.2.  It is also recommended for installations where you do not want to use Application.cfc, such as an installation where you don't want to use Mach-II throughout the website.  Bootstrapping Mach-II in the classic method involves editing two files: mach-ii.xml and index.cfm. Use the MachAppSkeleton download from www.mach-ii.com to make creating and configuring Mach-II applications easiest.

The mach-ii.cfc bootstrapper

As mentioned previously, the Mach-II bootstrapper is utilized at the Application.cfc level of your application. Using the bootstrapper is simple -- just add extends="MachII.mach-ii" to the cfcomponent tag of your Application.cfc.

As you can see, your Application.cfc file must extend a the MachII.mach-ii CFC in the core of the framework. This will not work if you cannot put Mach-II in your web root or cannot use server-wide mappings. Application specific mappings will not work as because your Application.cfc extends MachII.mach-ii before your application specific mappings have been processed and set. This is a ColdFusion engine problem and not a Mach-II framework defect. See I cannot use server-wide mappings or place Mach-II in my webroot, how can I extend MachII.mach-ii in my Application.cfc? for a workaround.

Mach-II 1.6 or higher

    <cfcomponent name="Application.cfc" extends="MachII.mach-ii" output="false">

        <!---
        PROPERTIES - APPLICATION SPECIFIC
        --->
        <cfset this.name = "YourApplication" />
        <cfset this.applicationTimeout = CreateTimeSpan(30,0,0,0) />
        ...More application specific attributes...

        <!---
        PROPERTIES - MACH-II SPECIFIC
        --->
        <!--- Set the path to the application's mach-ii.xml file --->
        <cfset MACHII_CONFIG_PATH = ExpandPath("/path/to/config/mach-ii.xml") />

        <!--- Set the app key for sub-applications within a single cf-application. --->
        <cfset MACHII_APP_KEY = "YourApplication" />

        <!--- Set the configuration mode (when to reload): -1=never, 0=dynamic, 1=always --->
        <cfset MACHII_CONFIG_MODE = -1 />

        <!--- Note the addition of this optional property. As applications grow, then tend to exceed request
        timeouts. Adding this property would allow the developer to set the timeout for application startup
        and if applications need to be reloaded if the config mode is 0 (dynamic). This is implemented  behind the
        scenes using <cfsetting requestTimeout="#MACHII_ONLOAD_REQUEST_TIMEOUT#"> and is automatically applied when
        the framework (re)loads --->
        <cfset MACHII_ONLOAD_REQUEST_TIMEOUT = 240 />

        <!---
        onApplicationStart() and onRequestStart() methods are inherited and do not need
        to be defined unless customized functionality is required
        --->

    </cfcomponent>

By default, the mach-ii bootstrapper for Application.cfc provides a few methods such as onApplicationStart, onRequestStart, onSessionStart and onSessionEnd. Unless more complex and customized functionality are required, you Application.cfc only needs to define a few application specific properties such as the application name and session/client management in additional to a few configuration properties for the bootstrapper to load your Mach-II application. We'll jump into the details later on, but the simplest of applications usually have a simple Application.cfc.

Mach-II 1.5 or lower

    <cfcomponent name="Application.cfc" extends="MachII.mach-ii" output="false">

        <!---
        PROPERTIES - APPLICATION SPECIFIC
        --->
        <cfset this.name = "YourApplication" />
        <cfset this.applicationTimeout = CreateTimeSpan(30,0,0,0) />
        ...More application specific attributes...

        <!---
        PROPERTIES - MACH-II SPECIFIC
        --->
        <!--- Set the path to the application's mach-ii.xml file --->
        <cfset MACHII_CONFIG_PATH = ExpandPath("/path/to/config/mach-ii.xml") />

        <!--- Set the app key for sub-applications within a single cf-application. --->
        <cfset MACHII_APP_KEY = "YourApplication" />

        <!--- Set the configuration mode (when to reload): -1=never, 0=dynamic, 1=always --->
        <cfset MACHII_CONFIG_MODE = -1 />

        <cffunction name="onApplicationStart" access="public" returntype="void" output="false">
            <!--- Add a higher request timeout if you application takes a long time to load
            <cfsetting requesttimeout="60" />
            --->
            <cfset LoadFramework() />
        </cffunction>

        <cffunction name="onRequestStart" access="public" returntype="void" output="true">
            <cfargument name="targetPage" type="string" required="true" />

            <!--- Only handle requests from the base index.cfm file --->
            <cfif arguments.targetPage EQ "/index.cfm">
                <cfset handleRequest() />
            </cfif>
        </cffunction>

    </cfcomponent>

The Bootstrapper Deconstructed

Overview

The first thing you need to do to get Mach-II loaded is that your Application.cfc needs to extend the mach-ii.cfc file. Remember that file names and CFC dot paths are case sensitive on *nix based servers so be careful when naming your Application.cfc (the 'A' must be uppercase) which extends 'MachII.mach-ii'. Example Application.cfc:

    <cfcomponent extends="MachII.mach-ii" output="false">

Set your application specific properties next:

    <!---
    PROPERTIES - APPLICTION.CFC SPECIFIC
    --->
    <cfset this.name = "myApplication" />
    <cfset this.applicationTimeout = CreateTimeSpan(30,0,0,0) />
    <cfset this.clientManagement = FALSE />
    <cfset this.sessionManagement = TRUE />
    <cfset this.sessionTimeout = CreateTimeSpan(0,0,30,0) />

You will need to set the "recommended" Mach-II specific properties next - we'll discuss these in more detail later on:

    <!---
    PROPERTIES - MACH-II SPECIFIC
    --->
    <!--- Set the path to the application's mach-ii.xml file --->
    <cfset MACHII_CONFIG_PATH = ExpandPath("/myApplication/config/mach-ii.xml") />

    <!--- Set the app key for sub-applications within a single cf-application. --->
    <cfset MACHII_APP_KEY =  this.name />

    <!--- Set the configuration mode (when to reinit): -1=never, 0=dynamic, 1=always --->
    <cfset MACHII_CONFIG_MODE = 0 />

We assume you already know about application properties that are specific to using Application.cfc. However, lets dive in deeper to the required and optional Mach-II properties.

Mach-II Properties

There are three recommended Mach-II properties and three optional ones that the Mach-II bootstrapper uses to load your Mach-II application.

Properties

Name Required Data Type Value Default Purpose
MACHII_CONFIG_PATH recommended absolute path ExpandPath( './config/mach-ii.xml' ) Specifies the location of your Mach-II configuration file. This requires an absolute path to your config file, so be sure to use ExpandPath when setting the location. It is best practice to use ExpandPath instead of hard coding an absolute path.
MACHII_APP_KEY recommended string GetFileFromPath( ExpandPath('.') ) This specifies the AppKey of your Mach-II application. This was added to allow multiple Mach-II applications to run under the same application scope (if you have used the same application name). You really don't have to worry about this unless you are building some complex peer applications. We recommend to use this.name as the value for this property which would give the AppKey the same value as the name of your application.
MACHII_CONFIG_MODE recommended -1, 0 or 1 0 This variables tells Mach-II when the configuration file (mach-ii.xml) should be reloaded to reconfigure your application components and model. For more information on what the values mean, see what does the config mode mean?.
MACHII_VALIDATE_XML optional boolean false Indicates whether or not Mach-II should validate the configuration file XML for proper syntax against a DTD.
MACHII_DTD_PATH optional absolute path ExpandPath( '/MachII/mach-ii_1_6_0.dtd' ) Sets the location of the DTD used to validate your configuration file syntax against if you have MACHII_VALIDATE_XML turned on. By default, it uses the DTD bundled with your version of Mach-II.
MACHII_ONLOAD_REQUEST _TIMEOUT optional numeric 240 Some applications take longer than the default request timeout set in your CFML engine's configuration. This configuration property set the request timeout to a higher number when the framework is loaded or reloading itself so it does not timeout. Increase this value to a higher number if your application exceeds the default of 240 seconds. (1.6+)
MACHII_HANDLE_ONLOAD optional boolean true Set if the framework should serve a "loading" template (1.9+)
MACHII_ONLOAD_TEMPLATE optional string /MachII/bootstrapper/defaultLoadingTemplate.cfm Set the template to show for loading of the framework. Defaults to Mach-II default template. (1.9+)
MACHII_ONREQUESTSTART _CONTENT_RESET optional boolean true Set if the framework should reset the response body should be reset before framework outputs. This is useful for integration Mach-II within other applications or frameworks (i.e. Mura, etc.) (1.9+)

Inherited Application Event Methods

In our example Application.cfc above, you might have noticed that the onApplicationStart and onRequestStart methods are missing and wondering how a Mach-II application could load itself and respond to client request without them. If you were to look at the mach-ii.cfc that you extended your Application.cfc, you will see that your Application.cfc inherited several methods including onApplicationStart, onRequestStart, onSessionStart and onSessionEnd. Most application do not require any additional configuration logic these methods and can use the inherited methods by default. Most of these methods are available in Mach-II 1.6 and some in Mach-II 1.8.

onApplicationStart() (1.6+)

Most Mach-II application will not need to override this inherited method. This method you will load the framework, using the loadFramework method within mach-ii.cfc. If you need to override the onApplicationStart method you need to call super.onApplicationStart() at the end of your onApplicationStart so the framework will load.

onApplicationEnd() (1.8+)

Most Mach-II application will not need to override this inherited method. If you need to override the onApplicationEnd method you need to call super.onApplicationEnd() at the end of your onApplicationEnd so the framework will cause any deconfigure methods to be called if the application timeout is exceeded.

onRequestStart() (1.6+)

The onRequestStart application event will fire at the beginning each request. Any requests that matches index.cfm will be handled by the framework when it calls handleRequest. If you override this method in your Application.cfc, you will need to either call super.onRequestStart(arguments.targetPage) or call manually decide if the target page is a .cfm file in which Mach-II should handle and call handleRequest() manually.

If you override this inherited method, you will need to set the output attribute value of your onRequestStart method to true otherwise the output the request will be a blank page.

onSessionStart() (1.6+)

Starting with Mach-II 1.6, onSessionStart is inherited by your Application.cfc from the bootstrapper. This method automatically calls all Mach-II plugins that define the onSessionStart plugin point. These plugin points reduce the need to have ad-hoc on session start logic in your Application.cfc and allows all "application like events" to be in the Mach-II architecture. If you need to override this method, you must call super.onSessionStart() at the end of your own onSessionStart method so Mach-II can execute all onSessionStart plugin points.

onSessionEnd() (1.6+)

Starting with Mach-II 1.6, onSessionEnd is inherited by your Application.cfc from the bootstrapper. This method automatically calls all Mach-II plugins that define the onSessionEnd plugin point. These plugin points reduce the need to have ad-hoc on session end logic in your Application.cfc and allows all "application like events" to be in the Mach-II architecture. If you need to override this method, you must call super.onSessionEnd(arguments.sessionScope, arguments.applicationScope) at the end of your own onSessionEnd method so Mach-II can execute all onSessionEnd plugin points.

Available Bootstrapper Methods

Method Name Syntax Purpose
loadFramework loadFramework() Loads the framework and must be called if onApplicationStart() is overrided (or call super.onApplicationStart() in your method. Do not call this methods outside of onApplicationStart(). If you need to reload your application, use the Mach-II Dashboard or use the reloadConfig() method (1.8.1+).
reloadConfig reloadConfig() Dynamically reloads your application configuration. Use this method to reload your application. Supported in Mach-II 1.8.1+.
handleRequest handleRequest() Handlers a Mach-II request. Logic to determine if it is a Mach-II request should wrap this function. This is typically a check to see if the targetPage matched index.cfm since Mach-II is front-controller framework. This function must be called if you override onRequestStart or you can use call super.onRequestStart() when overriding the inherited method.
getProperty getProperty("nameOfProperty", "optionalDefaultIfPropertyIsNotDefined") Gets a property from Mach-II. Can only be called after the onApplicationStart() application event has completed.
isPropertyDefined isPropertyDefined("nameOfProperty") Returns a boolean on whether or not the property exists. Can only be called after the onApplicationStart() application event has completed.

Common Errors

Incorrect Version of Mach-II

It is a common mistake to try using the new Application.cfc features (built-in onApplicationStart, onRequestEnd, etc. methods) with Mach-II 1.5. Doing this will not cause any errors but will result in a blank page being served for the request. If you are using Mach-II 1.5, you will need to define your own onApplicationStart method that calls the inherited loadFramework method and your own onRequestStart method that calls the inherited handleRequest method. We recommend that you upgrade to the latest release of Mach-II instead of using the old 1.5 version.

Another error is when you have a mapping to an older version of Mach-II and you try to override a method in the bootstrapper. A possible error could be The onApplicationStart method was not found or The onRequestStart method was not found. Be sure to check that your Application.cfc is extending the correct bootstrapper CFC and that your CFML engine is not accidentally resolving to the wrong boostrapper.

Blank Page or Empty Page Outputted on Each Request

If you override the inherited onRequestStart method, you will need to set the output attribute value of your onRequestStart method to true otherwise the output the request will be a blank page.

Using Mach-II with other Frameworks

If you use multiple frameworks in your project with Mach-II and all use same application name, you may get ApplicationScope error when you use Application.cfc as your mach-ii bootstrapper. Lets say /wwwroot is root folder without mach-ii. /wwwroot/user is folder which uses Mach-ii and Application.cfc as bootstrapper. Both have their application file with same application name. Both have same session time out (20 min) and same application time out (1 day). Now user comes to /wwwroot/index.cfm. so application and session time out set respectively. User waits for session time out, once session time outs, user goes to /wwwroot/user/index.cfm which will skip onApplicationStart and runs onSessionStart in Mach-ii.cfc. As there is no appkey in ApplicationScope for this application, it will throw error. Override onSesionStart in your mach-ii Application.cfc.

Additional Information

Clone this wiki locally