-
Notifications
You must be signed in to change notification settings - Fork 24
Using the Application.cfc Bootstrapper
- What is a bootstrapper?
- Which bootstrapper (e.g. Application.cfm/cfc) should I use?
- The mach-ii.cfc bootstrapper
- The Bootstrapper Deconstructed
- Available Bootstrapper Methods
- Common Errors
- Additional Information
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.
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 |
|
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 |
|
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. |
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.
<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.
<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 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.
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+) |
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.
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.
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.
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 youronRequestStart
method totrue
otherwise the output the request will be a blank page.
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.
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.
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. |
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.
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.
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.