What's New in Mach II 1.6 - Mach-II/Mach-II-Framework GitHub Wiki
A Quickstart for Current Mach-II Developers
- Changes to Mach-II 1.6 During Beta
- Mach-II 1.6 Goals
- Mach-II 1.6 Feature Overview
- CFML Engine Support
- Mach-II 1.6 Features in Depth
- What You Can Do To Help
- The Road Ahead
For those using Mach-II 1.6 since the beta, a special document is being maintained that lists the changes to the framework since the release of the beta.
Mach-II 1.6 Changes During Beta
In addition to the introduction of new features that Mach-II developers have requested, we had several other goals during the development of Mach-II 1.6.
- Maintain backwards compatibility. Mach-II 1.6 is 100% compatible with existing Mach-II applications currently running on earlier versions of Mach-II.
- Introduce caching at the controller level and build an extensible caching package that can be used independently from the MVC core of the framework.
- Introduce logging to replace the
TracePlugin
and build an extensible logging package that can be used independently from the MVC core of the framework. - Provide a way to asynchronously 'broadcast' a 'message' and have multiple listeners respond
- Keep the framework true to its mission. The mission of Mach-II is to provide CFML developers with a powerful, easy-to-use MVC framework that is extensible through its plugin and filter architecture. We are always extremely cautious when we add new features to Mach-II, and we weighed the inclusion of each of the new Mach-II 1.6 features very carefully. We feel that the features introduced in Mach-II 1.6 represent a logical evolution without diluting the framework through the addition of ancillary features directly into the framework core.
- Set the stage for Mach-II 2.0. We made several behind-the-scenes changes that will enable functionality we have planned for Mach-II 2.0, which we are currently targeting for mid-to-late 2009.
Although in terms of version numbering Mach-II 1.6 is only a "point release" over Mach-II 1.5, numerous new features are introduced in Mach-II 1.6. In addition to bug fixes and general performance improvements, the new features in Mach-II 1.6 are as follows:
- Caching Package, allowing for flexible, granular caching of data and rendered HTML content in Mach-II applications
- Logging Package, allowing for multiple logging types, channels, and levels
- Publish/Subscribe Listener Method Invocation, which allows for multiple listener methods to be invoked via the broadcast of a single message
- Improved
Application.cfc
bootstrapper, enabling the use ofonSessionStart()
andonSessionEnd()
events, eliminating the boilerplate code previously contained inApplication.cfc
, and other improvements - ColdSpring Property, which is a replacement for the deprecated ColdSpring Plugin. Please note that unlike the ColdSpring Plugin, which is maintained by the ColdSpring Project and distributed with ColdSpring as opposed to with Mach-II, the new ColdSpring Property is maintained by the Mach-II developers and is distributed as part of the Mach-II framework.
- New
onSessionStart
andonSessionEnd
plugin points - Utility Connector
Mach-II 1.6 officially supports:
- Adobe ColdFusion versions 7 and higher
- Open BlueDragon versions 7 and higher
- New Atlanta BlueDragon JX and J2EE, versions 7 and higher (note: Mach-II will not run on BlueDragon .NET)
We have been informed by Railo that Mach-II runs perfectly well on the latest versions of Railo, but we have not officially tested Mach-II 1.6 on Railo so at this point it is not officially supported. If you are running Mach-II 1.6 on Railo and run into issues, please let us know. We will try to add Railo to the list of officially supported CFML engines as soon as we can.
Note that some features of Mach-II will behave slightly differently or will not be available depending on the CFML engine on which Mach-II is run. For example, the threading capabilities in Mach-II 1.6 will currently only run on Adobe ColdFusion due to the differing implementation of <cfthread>
on BlueDragon and Open BlueDragon. Threading compatibility with Adobe ColdFusion 8 has recently been added to Open BlueDragon so full threading functionality on Open BlueDragon (and potentially BlueDragon) will be implemented in a future maintenance release of Mach-II.
If you are running Mach-II 1.6 on Open BlueDragon you do not need to write your code any differently. If Mach-II encounters something such as threading that will not run on Open BlueDragon or BlueDragon, Mach-II will handle this situation internally. In the case of threading, for example, Mach-II will simply execute the code sequentially.
As of Mach-II 1.6 we are no longer supporting compatibility with Adobe ColdFusion 6.1, so Mach-II 1.5 is the newest version of Mach-II that will run on Adobe ColdFusion 6.1. We will always support Mach-II on the newest version of Adobe ColdFusion and one version back, so as Adobe announces "end of life" for versions of ColdFusion, the next release of Mach-II will no longer be supported on, nor should it be expected to run on, versions of ColdFusion that are no longer supported by Adobe. We feel this strikes the best balance between maintaining compatibility over the most widely used versions of Adobe ColdFusion and allowing the Mach-II framework to take advantage of features added to new releases of ColdFusion.
One of the major new features in Mach-II 1.6 is a built-in caching package that can be used to cache data and output cached data within Mach-II applications. The new caching package allows for highly granular caching of data as well as rendered view output, and also supports named caches that can be created and cleared programmatically. The Mach-II caching package is highly flexible and supports multiple caching strategies. Mach-II 1.6 includes Time Span and Least Recently Used (LRU) caching strategies, and due to the extensible nature of Mach-II caching package, additional strategies can be developed relatively easily.
Since Mach-II is responsible for the controller (listeners) and views inside a web application, the Mach-II caching package handles caching of both data and view output in a highly granular way. The native Mach-II caching solution allows for caching the result of one or more listener calls, i.e. notify commands specified in the XML configuration file, and can also cache the results of rendered views, i.e. view-page commands specified in the XML configuration file. Calls to subroutines may also be cached.
In addition to the automatic refreshing of caches based on the caching strategy used, the Mach-II caching package also makes it easy for developers to control the state of caches and clear them when data has become stale. For example, if a user updates a list of products and this list is cached by Mach-II, the developer is able to clear the products cache on demand. This causes the products cache to be re-populated the next time the products list is requested.
The default caching implementation in Mach-II 1.6 includes the previously mentioned time span and LRU caching strategies. In addition to being able to create new caching strategies, developers may also create entirely new caching implementations that may be plugged into Mach-II. For example, a caching implementation that leverages the memcached project or ehcache project could be created by extending the AbstractCacheStrategy
CFC.
Various metrics related to cache performance are also included in the caching package. The caching stats can be viewed by using the new Logging Package (details below), or in the new Mach-II Dashboard which will soon be released in beta.
Because of its flexible, modular nature, Mach-II's caching package may also be used independently of Mach-II, provided some sort of custom loader is written. Once the caching package is loaded into this custom context, all the functionality is available just as if the caching package were operating within the Mach-II framework.
Additional information about the Mach-II 1.6 Caching Package may be found in the original caching specification as well as the Intro to Caching wiki page.
The other major new functionality added to Mach-II 1.6 is the logging package, which includes numerous minor changes to the internals of the framework to vastly expand the information logged by Mach-II internally, as well as the introduction of the logging package itself. The logging package gives developers access to a complete logging solution, including the ability to log multiple levels of messages across multiple channels and loggers. As with the Mach-II caching package, the logging package is also a completely modular, stand-alone package that may be used outside the context of Mach-II, provided a custom loader is written. The logging package may also easily be extended to incorporate logger types other than the three included with Mach-II.
The simplest usage of the logging package is as a replacement for the deprecated TracePlugin
, which outputs basic information about what occurred during the request at the bottom of the screen. Using this feature of the new login package is as simple as adding a single property to the mach-ii.xml file:
<property name="Logging" type="MachII.logging.LoggingProperty" />
This leverages the MachIILogger that is contained in the Mach-II framework core, and provides information and timings for everything that occurs during the request.
In addition to the MachIILogger mentioned above, the other loggers included with Mach-II are:
-
CFLog
Logger: writes information to standard log files using<cflog>
-
EmailLog
Logger: sends log information via email
The loggers may be used in combination with one another, and the log level that applies to each logger is configurable. The logging package adheres to standard log level nomenclature (trace
, debug
, info
, warn
, error
, fatal
) that is used by the Apache Commons Logging project and other common loggers. For example, the CFLog
Logger could log information through the warn
level, while a log level of error
or fatal
could trigger the EmailLog
Logger to send alerts via email.
In addition to standard logger behavior, developers may add their own logging messages programmatically that will be broadcast to all registered loggers.
Additional information about the Mach-II 1.6 Logging Package may be found in the Intro to Logging wiki page.
Traditionally in Mach-II event handlers, listeners have been notified using the <notify>
command. For example, if in an event handler myListener
needs to execute myMethod
and store the results in myEventArg
, the following code would be used:
<notify listener="myListener" method="myMethod" resultArg="myEventArg" />
This is a convenient and direct way of doing things, and allows developers to see all of the listener notifications and method invocations by looking at the event handler code in the mach-ii.xml
configuration file.
It is not uncommon, however, to notify numerous listeners during the course of an event, and in some cases these multiple listener notifications may be used on several events, potentially leading to redundant code between event handlers. Furthermore, some developers prefer to use a more decoupled approach to listener notification, in which a single message is broadcast as part of an event handler, and multiple listeners that have registered an interest in this message may all execute methods based on this single message broadcast.
To address this situation, Mach-II 1.6 introduces a new publish/subscribe method of listener notification, which allows a single message to be broadcast as part of an event handler, and this message broadcast in turn triggers multiple listener notifications. Note that the previous method of using a <notify>
command for each listener notification is not being deprecated; the new publish/subscribe functionality is simply an additional option for listener notification.
To use this new method of notifying listeners, the event handler includes the new <publish>
command:
<event-handler event="myEvent" access="public">
<publish message="needMyStuff"/>
</event-handler>
Listeners interested in the needMyStuff
message are registered in a new <message-subscribers>
section of the mach-ii.xml
configuration file, and it is here that the methods to be invoked based on the message publication are declared:
<message-subscribers>
<message name="needMyStuff" multithreaded="true" waitForThreads="true" timeout="60">
<subscribe listener="listener1" method="method1" resultArg="stuff1"/>
<subscribe listener="listener2" method="method2" resultArg="stuff2"/>
</message>
</message-subscribers>
With this code in place in the mach-ii.xml
configuration file, when myEvent
is announced, the message needMyStuff
is published, and the subscribers to this message, which in this case are listener1
and listener2
, invoke the appropriate methods and place the results to these method calls in the event object via the resultArg
attribute of the subscribe command.
In addition to the convenience and decoupled aspect of this style of listener notification, by using publish/subscribe the calls to the listeners may be multithreaded by use of the multithreaded
attribute in the message declaration. This functionality leverages the new <cfthread>
tag in Adobe ColdFusion 8. Due to the differences in implementation of <cfthread>
among the different CFML engines, the multithreaded
attribute of a message declaration is currently ignored in other CFML engines, though support will be added for Open BlueDragon and potentially other engines in a future maintenance release of Mach-II.
By multithreading listener notifications, each notification within the message block will be executed simultaneously in an independent thread, which typically results in improved performance. The waitForThreads
attribute indicates that all threads within the message block must complete before the execution of the event handler resumes. If one of the listener notifications is a background process, such as starting a lengthy report generation process, performing logging, etc. then waiting for all the threads to complete may not be necessary.
Additional information about the new publish/subscribe listener invocation in Mach-II 1.6 may be found in the Intro to Message / Subscriber Listener Notification.
In order to simplify the overall code involved with the Application.cfc
bootstrapper that was introduced in Mach-II 1.1.1 as well as give developers access to all of the events available in Application.cfc
, the following methods are now included in mach-ii.cfc
, which application-specific Application.cfc
files extend:
-
onApplicationStart()
: sets request timeout and callsloadFramework()
-
onRequestStart()
: checks forindex.cfm
and callshandleRequest()
-
onSessionStart()
: callsonSessionStart
plugin points (see "New Plugin Points" below for details) -
onSessionEnd()
: callsonSessionEnd
plugin points (see "New Plugin Points" below for details)
In addition, the boilerplate code that was previously necessary to include in Application.cfc
has been moved to mach-ii.cfc
, so unless any of the methods in mach-ii.cfc
need to be overridden for custom functionality, only basic application-specific variables (e.g. application name, session and application timeouts, etc.) will need to be included in Application.cfc
. This also allows for much easier module integration, because the module's Application.cfc
will not need to be edited in order to be incorporated into an existing application.
A new MACHII_ONLOAD_REQUEST_TIMEOUT
variable has also been added to the framework, and this controls the request timeout setting for framework reloads independently of the general request timeout setting. The default value is 240 seconds, but this can be overridden for usual cases when you have a particularly large applications that may take longer than 240 seconds to load.
Additional information about the Application.cfc bootstrapper improvements in Mach-II 1.6 may be found on the using the bootstrapper wiki page.
The ColdSpring Property (MachII.properties.ColdspringProperty
) is a property CFC that is used to enable ColdSpring functionality in Mach-II applications. ColdSpring is a dependency injection framework that also has aspect-oriented programming (AOP) and other functionality, and is a powerful framework to use in conjunction with Mach-II.
In previous versions of Mach-II, ColdSpring integration was handled with a ColdSpring Plugin that was managed by the ColdSpring project. The ColdSpring Plugin is now deprecated for all versions of Mach-II 1.5 and higher.
Beginning with Mach-II 1.6, the ColdSpring Property supports a new depends
attribute in CFCs that extend any Mach-II framework objects such as Listeners, Filters, Plugins, etc. This allows for dependencies in CFCs to be resolve by ColdSpring without the necessity of creating getters and setters for these dependencies or using constructor argument injection. For example, if PersonListener
has a dependency on PersonService
, the <cfcomponent>
tag can include the new depends
attribute and provide a comma-delimited list of bean IDs that are defined in the ColdSpring XML configuration file:
<cfcomponent
displayname="PersonListener"
output="false"
extends="MachII.framework.Listener"
depends="personService">
Even though getters and setters for dependencies are not explicitly included in the Listener itself, these methods are still used to access the dependencies, because they are created automatically:
<cfset var people = getPersonService().getPeople() />
Note that the original CFC file is not changed to include the getters and setters in the file that is stored on disk, so all of the CFC's original code remains untouched. The getters and setters are added to the instance of the CFC that is stored in RAM when the application is loaded.
Another new feature of the ColdSpring Property is the ability to automatically inject beans into the Mach-II property manager, thus making custom beans available as properties within Mach-II applications. This is controlled by the beansToMachIIProperties
parameter that is part of the configuration of the ColdSpring Property. This parameter is configured using a struct which is defined in the Mach-II XML configuration file, and each element of the struct is defined as a name/value pair, where the name is the ColdSpring bean ID, and the value is the Mach-II property name.
Additional information about the ColdSpring Property may be found on the Using the New ColdSpring Property wiki page, as well as in the comments in the source code of the ColdspringProperty.cfc.
The Utility Connector (MachII.util.UtilityConnector
) is a helper component that allows you to leverage Mach-II's caching and logging packages and extend this functionality to the model/business logic layer of your application. More specifically, the Utility Connector is designed to allow developers to incorporate Mach-II's logging and caching functionality with ColdSpring or another bean factory.
Mach-II's caching and logging packages have been designed to be utilized both as part of Mach-II's MVC architecture as well as independently of Mach-II. Since the logging and caching packages themselves are agnostic of the Mach-II framework, using them in the model layer of an application does not create a coupling to Mach-II in the model layer. By writing a custom loader for the logging and caching packages, Mach-II could be removed from your application and these packages could be used outside of Mach-II. Mach-II ships with Mach-II-specific loaders (MachII.logging.LoggingProperty
and MachII.caching.CachingProperty
) for logging and caching, but the code necessary to load these packages outside of the context of Mach-II would be rather trivial to create.
One example of using the Utility Connector is enabling logging within the model of an application using ColdSpring. First, the Utility Connector is defined as a bean in the ColdSpring configuration file:
<bean id="utilityConnector" class="MachII.util.UtilityConnector"/>
Next, utilityConnector
is defined as a factory called logFactory
:
<bean id="logFactory"
factory-bean="utilityConnector"
factory-method="getLogFactory" />
Finally, the logger is set as a property of a model bean that is managed by ColdSpring:
<bean id="someBean"
type="dot.path.to.SomeBean">
<property name="log"><ref bean="logFactory"/></property>
</bean>
With this configuration in place, someBean
now has the ability to perform logging via Mach-II's logging package. Caching is integrated into an application's ColdSpring managed beans in very similar fashion.
Additional information about the Utility Connector may be found in the Using the Utility Connector wiki page.
The following new plugin points have been added in Mach-II 1.6:
onSessionStart
onSessionEnd
This allows developers to interact with onSessionStart
and onSessionEnd
events in plugins. In order to have Mach-II call these plugin points, you must be using Application.cfc that extends the MachII.mach-ii
bootstrapper. For more information on using the Application.cfc bootstrapper check out Using the Bootstrapper and for information pertaining to writing plugins check out Introduction to Plugins.
- The
<event-arg>
command added theoverwrite
attribute which takes a boolean and defaults to true. When theoverwrite
attribute is set to false, this command works similar to<cfparam>
by not overwriting the event-arg if it already exists in the event object. - The
<redirect>
command added thepersistArgIgnore
attribute which takes a list of event-args to ignore when persisting args across a redirect. This attribute is ignored whenpersistArgs
is defined. This is useful when the list of args to persist is longer than the total number of args you do not want to persist.
First and foremost, thank you for using Mach-II! We continue to strive to make Mach-II the best MVC framework for CFML development, and your use of and feedback about Mach-II is a vital part of our development process.
If you'd like to help further, there are many ways to do so:
- Write an FAQ or other documentation on the wiki
- Report a bug
- Request a new feature
- Add your site/company to the "Who's Using Mach-II" page on mach-ii.com (coming soon!)
- Contact us to set up an interview or case study that we can publish on mach-ii.com
- Tell your friends and colleagues about Mach-II
In terms of helping us, a little goes a long way. If everyone using Mach-II spent even 10 minutes helping out with documentation, that translates into a massive number of man hours contributed to the project.
After we recover from the 1.6 release, we're going to dive right into small release of Mach-II 1.8 which will focus of toolkit enhancements. Why 1.8? Because it's half-way between Mach-II 1.6 and Mach-II 2.0, which we're targeting for release in the first half of 2009. Why the version number change to 2.0? When you see what we have planned, we think you'll understand. ;-)