<?xml version="1.0" encoding="utf-8"?>
			
			<rss version="2.0">
			<channel>
			<title>Iterate Me: Brian Klaas: Blog</title>
			<link>http://www.iterateme.com/blog/index.cfm</link>
			<description>Educational, software development and pop culture all mashed up.</description>
			<language>en-us</language>
			<pubDate>Mon, 06 Sep 2010 20:05:32-0400</pubDate>
			<lastBuildDate>Thu, 02 Sep 2010 09:21:00-0400</lastBuildDate>
			<generator>BlogCFC</generator>
			<docs>http://blogs.law.harvard.edu/tech/rss</docs>
			<managingEditor>brian@iterateme.com</managingEditor>
			<webMaster>brian@iterateme.com</webMaster>
			
			<item>
				<title>cfcache Early, cfcache Often, &apos;Cause It&apos;s Just So Darn Easy</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/9/2/cfcache-Early-cfcache-Often-Cause-Its-Just-So-Darn-Easy</link>
				<description>
				
				Each new version of ColdFusion (be it from Adobe, Railo or OpenBD) brings with it a raft of new features. As a busy developer just trying to get things done, it&apos;s easy to skip over most of the new features and use what you&apos;ve always used. I&apos;d like to share a brief story about the &amp;lt;cfcache&amp;gt; tag in Adobe ColdFusion 9 and why it&apos;s the one tag in CF9 that you should start using now.

Improving performance is always an issue, regardless of the technology you&apos;re using to build and deploy Web sites. I ran into an issue yesterday where a tool that had worked just fine suddenly began to experience significant slowdowns. The tool is for managing groups of students in classes. Normally, a class will have 3-7 groups of students. In two cases, relatively large classes (100+ students) needed to divide students into groups in multiple ways. In one class, they ended up with 42 different groups of students. In the other, they ended up with almost 100 groupings. With this many groups, the main listing page of all groups in these courses started to run quite slowly. Response times dropped from a couple of seconds to 40+ seconds.

After a brief investigation, the issue was that core information about the class was being retrieved for each and every group on the page. The core information about the class included quite a bit of information, usually returned in approximately 420ms, and the increase in repeat calls to get this information was really slowing things down. 

&lt;blockquote style=&quot;background-color:#efefef; padding: 4px;&quot;&gt;
I&apos;m not going in to the discussion of using queries or structs instead of business objects for performance reasons at this point. Refactoring the course data retrieval service to return a simple struct or query would definitely improve performance, but a) that&apos;s not what this post is about and b) would involve mucking with core business objects and that&apos;s not something I wanted to do given the need to quickly address the situation.
&lt;/blockquote&gt;

Repeatedly retrieving the same data from the data source is costly and foolish. A quick solution to the problem was to cache the required data and use that cached information instead. As the core information about a course doesn&apos;t change very often, I could cache this information for 5 minutes with no problems and get a nice performance boost.

Until CF9, you couldn&apos;t cache objects without rolling your own struct-based caching code. In CF9, though, the &lt;a href=&quot;http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d5a.html&quot;&gt;&amp;lt;cfcache&amp;gt; tag&lt;/a&gt; makes it super easy to cache objects, page fragments, query results, or whatever you need.

As this call to get the core course information was being made a number of times in the same CFC, I refactored this call in to a private function. Here&apos;s the code:

&lt;code&gt;
&lt;cffunction name=&quot;getCourseInfo&quot; access=&quot;private&quot; output=&quot;false&quot; returntype=&quot;course&quot;&gt;
		&lt;cfargument name=&quot;courseID&quot; type=&quot;numeric&quot; required=&quot;yes&quot;  /&gt;
		&lt;cfset var courseNameInCache = &quot;courseID&quot; &amp; arguments.courseID /&gt;
		&lt;cfset var cachedCourseInfo = cacheGet(courseNameInCache) /&gt;
		&lt;cfset var course = 0 /&gt;
		&lt;cfif isNull(cachedCourseInfo)&gt;
			&lt;cfset course = variables.courseService.getCourse(arguments.courseID) /&gt;
			&lt;cfset cachePut(courseNameInCache, course, CreateTimeSpan(0,0,5,0)) /&gt;
		&lt;cfelse&gt;
			&lt;cfset course = cachedCourseInfo /&gt;
		&lt;/cfif&gt;
		&lt;cfreturn course /&gt;
&lt;/cffunction&gt;
&lt;/code&gt;

The key to this function are the cacheGet, isNull, and cachePut functions. You use cacheGet(itemName) to put something in to the cache, and cacheGet(itemName) to get something out of the cache. Super simple, right?

This function shows off some of the issues you need to be aware of when using CF9&apos;s built-in instance of &lt;a href=&quot;http://ehcache.org/&quot;&gt;Ehcache&lt;/a&gt;.

&lt;ul&gt;
&lt;li&gt;I&apos;ve been asked &quot;How do you make sure you have a unique name for the item you want to put in the cache and how do you remember that unique name later when you need to get the item from the cache?&quot; The first cfset line takes care of that. It&apos;s convenient to generate the name for the item in the cache using a key value associated with that item, like courseID. You just have to make sure that no other item anywhere in the cache is going to have the same name.&lt;/li&gt;
&lt;li&gt;You need to check to see if an item in the cache exists, otherwise how will you know to use the cached item or put the item in the cache? That&apos;s what the  cacheGet(courseNameInCache) and the isNull(cachedCourseInfo) calls do. You first try to get the item out of the cache. If it exists, great! If not, CF will return a null value for the item in the cache. If you get a null value for the item in the cache, you need to put the item in the cache.&lt;/li&gt;
&lt;li&gt;If the item isn&apos;t in the cache, you need to generate the item and then put it in the cache via cachePut(itemName). Again, be sure to make your item names unique!&lt;/li&gt;
&lt;li&gt;If the item &lt;em&gt;is&lt;/em&gt; in the cache, return the cached version of the item.&lt;/li&gt;
&lt;/ul&gt;

One concern that&apos;s often raised about using the default &amp;lt;cfcache&amp;gt; setup in ColdFusion 9 is that items put in the cache are put in the JVM along with everything else that ColdFusion puts there. As such, the items you cache will take up some memory, along with the CF runtime, your application code, items in persistent scopes (server, application, session), and objects generated on a per-request basis. However, in many cases, you&apos;re going to be caching items that take up 1K of memory or less. That means it&apos;ll take about 1000 items in the cache before you use 1MB of memory. Unless you are caching really big data sets using &amp;lt;cfcache&amp;gt; or expect that you&apos;ll have hundreds of thousands of items cached on a server with limited memory, this generally won&apos;t be a problem and you shouldn&apos;t let caching items in memory scare you. (You can &lt;a href=&quot;http://www.brooks-bilson.com/blogs/rob/index.cfm/2009/11/17/Caching-Enhancements-in-ColdFusion-9--Part-6-Configuring-Caches-and-Working-with-ehcachexml&quot;&gt;configure CF9 to use a separate, standalone instance of Ehcache&lt;/a&gt;, should you so desire.)

To wrap up my little story, the end result of taking 15 minutes to write up this simple caching function, run my unit tests, and deploy the change was a reduction in page load times from 40+ seconds to under two (2) seconds. That&apos;s an excellent improvement for so little work. 
				</description>
				
				<category>ColdFusion</category>				
				
				<pubDate>Thu, 02 Sep 2010 09:21:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/9/2/cfcache-Early-cfcache-Often-Cause-Its-Just-So-Darn-Easy</guid>
				
			</item>
			
			<item>
				<title>The Best Online Guide to the ColdFusion Debugger</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/8/16/The-Best-Online-Guide-to-the-ColdFusion-Debugger</link>
				<description>
				
				&lt;a href=&quot;http://www.carehart.org/blog/&quot;&gt;Charlie Arehart&lt;/a&gt; is an indefatigable contributor to the ColdFusion community. He always manages to dig through the dark and unexplored corners of CF and CF-related products, and comes up with some excellent gems and insights along the way.

One area of ColdFusion development that still remains something of a black art to me is getting the debugger in ColdFusion Builder (or, previously, CFEclipse/Eclipse) up and running. The official CF docs aren&apos;t particularly great on this front. While they give you the basics of setting up the debugger, they don&apos;t cover all the little details and gotchas that can make getting the debugger to run seem like the darkest of Dark Arts.

Today, Charlie posted an &lt;a href=&quot;http://www.forta.com/books/0321679199/CFWACK9-2-echapters.pdf#page=71&quot;&gt;awesome, detailed guide to setting up and using the ColdFusion Debugger&lt;/a&gt;. It&apos;s in a PDF which contains three chapters from the &lt;a href=&quot;http://www.amazon.com/dp/0321679199?tag=carehartorg-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321679199&amp;adid=1D5J2GG9MKF3HT3J5QEF&amp;&quot;&gt;ColdFusion 9 Web Application Construction Kit, Volume 2&lt;/a&gt;, that weren&apos;t included in the final version of the book because of page count limitations.

I&apos;ve read a number of blog entries, the official docs, and even a Fusion Authority guide to using the debugger in CFBuilder, but none are as clear or detailed as Charlie&apos;s guide. He covers the issues with setup (especially if you&apos;re on a multi-server install or debugging against a remote server) and the details of the sometimes persnickety debug session itself. It should be your first (and probably only) read if you want to get started with CF debugging.

If you download the PDF, you also get a chapter on Globalization and one on Error Handling. Sweet! 
				</description>
				
				<category>ColdFusion</category>				
				
				<pubDate>Mon, 16 Aug 2010 08:08:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/8/16/The-Best-Online-Guide-to-the-ColdFusion-Debugger</guid>
				
			</item>
			
			<item>
				<title>Setting Up SSL for Local Development on Mac OS 10.6</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/8/6/Setting-Up-SSL-for-Local-Development-on-Mac-OS-106</link>
				<description>
				
				I spent the better part of the other morning reading various Web entries about setting up SSL on a local development machine running Mac OS 10.6. If you build sites that utilize SSL, it&apos;s sometimes valuable to be able to test this functionality locally, especially if you have events in your Web app that switch from SSL to non-SSL connections.

The resource I found that finally got everything working was &lt;a href=&quot;http://blog.dmcinsights.com/2009/03/06/enabling-ssl-on-mac-os-x-leopard/&quot;&gt;Larry Ullman&apos;s blog post &quot;Enabling SSL on Mac OS X Leopard.&quot;&lt;/a&gt; Everything posted there works for 10.6 (Snow Leopard) as well as 10.5 (Leopard). The same couldn&apos;t be said for other blog posts and, unfortunately, some of the tips on MacOSXHints.com.

Note that you don&apos;t need to install MAMP or MAMP Pro to get things working. If you&apos;re developing with ColdFusion, there&apos;s no real need for MAMP as 10.6 (and 10.5 before it) come pre-installed with Apache. You just need to install a CF server.

As Larry and the author of the Apple article which Larry references both note, you&apos;re not making a real, valid SSL certificate here. You&apos;re going to have to tell Safari/Firefox/Chrome that it&apos;s OK that you can&apos;t validate the authenticity of your localhost site. 
				</description>
				
				<category>ColdFusion</category>				
				
				<pubDate>Fri, 06 Aug 2010 15:56:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/8/6/Setting-Up-SSL-for-Local-Development-on-Mac-OS-106</guid>
				
			</item>
			
			<item>
				<title>On App Inventor: Speaking the Language of Novices</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/7/12/On-App-Inventor-Speaking-the-Language-of-Novices</link>
				<description>
				
				&lt;a href=&quot;http://appinventor.googlelabs.com/about/&quot;&gt;Google&apos;s App Inventor&lt;/a&gt; is a great idea. Empowering consumers to create is always a good thing. Visual Basic was the key to Microsoft&apos;s long-time success. Map making tools are the reason why Warcraft III and Starcraft still sell on retail shelves, more than a decade after their release. iMovie, Windows Movie Maker and its counterparts have helped make YouTube the site for almost every Web meme of the last five years.

Visually-oriented IDEs are a great way to develop software quickly. Visual Basic and Delphi are two classic examples of this, and their tradition of partial WYSIWYG views carries on to Visual Studio and Flex Builder today. (I&apos;ve also made the argument that if Adobe wants CFBuilder extensions to really take off, they need a visual UI to create them.)  They&apos;ve even evolved to have a similar visual language: panels spread out on the screen which allow for inter-panel communication and interaction, playing off visual and interaction patterns common to many IDEs. When you fire up Eclipse or Visual Studio, you, as a programmer, can say &quot;Oh, I know the basics of how this IDE works because it looks like other IDEs I&apos;ve worked with.&quot;

All of those tools, however, expect that the user has some kind of fundamental understanding of the basics of programming: simple data structures, simple logic controllers, and so on. You simply can&apos;t get by without them.

Now let me say that I&apos;ve had minimal direct experience with Google&apos;s App Inventor. I don&apos;t think that&apos;s a problem here because I want to talk about &lt;em&gt;first impressions&lt;/em&gt;, as those mean a lot to the average, non-technical user at whom Google is targeting the product.

Take a look at this screenshot from the product&apos;s home page:

&lt;img src=&quot;/blog/images/posts/appInventor.png&quot; align=&quot;center&quot; width=&quot;600&quot; height=&quot;369&quot; border=&quot;1&quot; alt=&quot;App Inventor Demo Screen&quot; /&gt;

The focus of the UI is on the simulated phone screen in the middle of the window, as it should be. Take a look at the list of controls under &quot;Palette,&quot; on the left. There you&apos;ll see titles for controls such as &quot;Canvas,&quot; &quot;ListPicker,&quot; and &quot;TinyDB.&quot; Although there is a question mark next to each which, when clicked, tells the user what the control is, that text (and other text on the screen) is very much the language of the programmer and not the user. A non-technical, non-programmer, average, everyday Android phone user (who is the target user of App Inventor) would probably look at that and say &quot;What the heck is a ListPicker?&quot; I&apos;ve worked with a lot of &quot;non-technical, non-programmer users,&quot; and know pretty well that when any &quot;programmer-ese&quot; comes in to play in the UI, users tend to be taken aback and almost immediately take a combative approach to this UI written in a language other than their own.

This programmer-centric language works its way in to other elements in very subtle ways. Look at the properties you can manipulate in the &quot;Components&quot; and &quot;Properties&quot; panels. The text which describes the properties you can manipulate, while clear, is written in camel case &amp;mdash; a programmer&apos;s, not average user&apos;s, convention. &quot;CheckBox1&quot; could just as easily have been displayed as &quot;Check Box 1.&quot; The same goes for &quot;BackgroundColor&quot; and &quot;BackgroundImage.&quot; I know this sounds trivial, but it&apos;s clearly the work of programmers who expect that users will get or, at least, grow accustomed to the way software is written by programmers, not &quot;average end users.&quot;

I also have to wonder if the basic assumption of the standard IDE UI as the default UI is an appropriate one. In my experience, users are task-focused. They want to be able to make a movie from video on their camera and upload it to YouTube. They want to write a letter to their congressman about an issue that is important to them. They want to set up a quiz for the students in their class to take. As users are task-focused (and not document focused), an application should start with smart defaults and help a user accomplish basic tasks quickly. Instead of showing the standard IDE UI at startup, App Inventor may be better served with a &quot;Start Screen&quot; which could ask:

&lt;blockquote&gt;
What kind of application would you like to build?
&lt;ul&gt;
&lt;li&gt;One that uses data from my Twitter account.&lt;/li&gt;
&lt;li&gt;One that uses maps to display places that are important to me.&lt;/li&gt;
&lt;li&gt;One that lets me chat with my friends.&lt;/li&gt;
&lt;li&gt;None of the above.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

The options presented here, when selected, would then pull together some of the basics for the application, saving the &quot;average user&quot; quite a bit of time and lay out most of hte plumbing required to get their desired application off the ground. This &quot;Start Screen&quot; could be turned off in the application&apos;s preferences for user who don&apos;t want to be bothered with this kind of getting started page.

The blocks tool that the team has devised to map out the internal logic of the application is really smart. It makes visualizing the logic clear and it&apos;s easy to drag and drop components in to the right order. No-code development environments like this are key to getting &quot;average users&quot; to use the tool to create applications that do what they want.

I&apos;ve used &quot;average users&quot; in quotation marks throughout this entry. That&apos;s because I don&apos;t think the real audience is &quot;average users&quot; &amp;mdash; meaning someone who owns a smartphone but hasn&apos;t developed software before. The tool was developed by university-level faculty and targeted towards students at various levels (elementary, middle, high and university) but in the context of teaching software development. As such, I believe the tool makes the fundamental assumption that you have to have &lt;em&gt;some&lt;/em&gt; knowledge of the art of programming. That assumption informs the design of the UI and how users interact with it. It makes it vastly simpler for individuals to develop applications (even me!), but it&apos;s not a tool that can be used by just anyone with experience with smartphones.

App Inventor was created by a lot of people much smarter than I. It&apos;s also still in beta and something I know that the team will improve upon over time. I just have to point out that if they really want to create something which allows the average user of a cell phone to build their own applications, they need to create a UI that, from start to end, reads in the way that an average, non-programmer user would understand. 
				</description>
				
				<category>UI</category>				
				
				<category>Educational Technology</category>				
				
				<pubDate>Mon, 12 Jul 2010 09:08:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/7/12/On-App-Inventor-Speaking-the-Language-of-Novices</guid>
				
			</item>
			
			<item>
				<title>How My iPad Has Unexpectedly Replaced My Desktop. Sort Of.</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/5/24/How-My-iPad-Has-Unexpectedly-Replaced-My-Desktop-Sort-Of</link>
				<description>
				
				I&apos;m fortunate enough to have been given an iPad by my employer for R&amp;D purposes. I certainly wasn&apos;t looking to buy one on my own. I have an iPhone, which I think is a fantastic mobile computing device (yes, even though most of my software development work is done using Adobe&apos;s tools &amp;mdash; we&apos;re allowed to live in both camps, if we want, you know). I didn&apos;t see the point in the iPad.

I also happen to have a PowerMac G5 that I purchased in June 2004 as my primary desktop computer at home. It&apos;s a bit old and underpowered now, but it still does the job. I even play and &lt;a href=&quot;http://www.wowwiki.com/Raid&quot;&gt;raid&lt;/a&gt; in &lt;em&gt;World of Warcraft&lt;/em&gt; using that box. That is, until the weekend before last. That Saturday was the day that my video card decided to completely blitz out, making any display rendering almost totally unusable. I can still perform certain tasks on the computer, but that&apos;s mostly through muscle memory and deep recognition of application windows. The display is largely illegible. I&apos;ve cleaned the card, using pressurized air to blow off every spec of dust off the card, to no avail. Because the machine is so old and because replacing the card will set me back about $350-400 (because the machine and the cards for it are so old), there&apos;s no good reason not to replace the machine.

The iMac line (which I&apos;d buy from to replace this desktop) is &lt;a href=&quot;http://buyersguide.macrumors.com/#iMac&quot;&gt;nearing the end of its current cycle and due for a refresh&lt;/a&gt;. I don&apos;t want to buy a new iMac only to find the line refreshed in the next 14 or 21 days. I can only go for so long without a desktop at home, so what to do?

My partner has been gracious enough to let me play WoW on his computer (in spite of the fact that he intensely dislikes the game and the years of late nights I&apos;ve spent as a raid leader). That&apos;s one problem down. I don&apos;t do a lot of digital photography or video, so there&apos;s no urgency there. I can still buy music and apps via iTunes because I can kind of make things out on the screen on my desktop (though I&apos;m sure I&apos;ll soon buy something I did not want because of this on-screen guesswork), so that&apos;s another problem that&apos;s handled. But what about my daily Web browsing activities, and shopping, and email?

Enter the iPad.

I&apos;ve been remarkably surprised at how well the iPad takes care of my consumption activities on the Internet. Between regular old Web sites and specialized apps (like a news reader for my 150+ RSS feeds or LogMeIn Ignition for remote desktop control), I&apos;ve not had to give up much in terms of going about my normal Web consumption activity on my iPad. I don&apos;t play Farmville (or any Flash games), and most movie trailers I watch are in QuickTime, so I don&apos;t miss Flash too terribly. It&apos;s easier on the eyes than my iPhone, and the increased physical space and gestural flexibility make it a better choice for my daily Web activities than the iPhone.

But I can&apos;t run Eclipse, so no development work for me. If I need to do some management in Adobe Connect (or teach using Connect, for that matter), I have to turn to my partner&apos;s desktop. If I ever get around to making a DVD of my family&apos;s videos from our 2009 African safari, it&apos;s not going to happen on the iPad. And I still need to connect to my desktop in order to sync my iPad (or iPhone). I can download music and apps over WiFi, but I&apos;d like to have everything backed up so when I do move to a new machine it&apos;s all seamless and stuff. (That part of the process once again shows that Apple should cut the cord between their mobile devices and the desktop &amp;mdash; in spite of the halo effect and the extra sales they get from it &amp;mdash; and take a cue from Google&apos;s Android 2.2 OS and push cloud sync front and center.)

As many critics have pointed out, the iPad is not a good creation device on a number of fronts (software development being a big one), but it&apos;s a pretty damn fine device for consumption. No one complains that you can&apos;t develop desktop/mobile/Web apps on your XBox 360 or PlayStation, now do they? 

Having used the iPad for a few weeks now, I can easily see how it will replace an extra computer in the house, or two. I can see how it will eventually grow in to a device for creation and consumption (though I think consumption will be its primary focus for a number of product iterations). It lacks the power and flexibility of my desktop, but like all things technological, isn&apos;t that just a matter of time? 
				</description>
				
				<category>Apple</category>				
				
				<pubDate>Mon, 24 May 2010 08:53:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/5/24/How-My-iPad-Has-Unexpectedly-Replaced-My-Desktop-Sort-Of</guid>
				
			</item>
			
			<item>
				<title>Mach-II Modules Don&apos;t Automagically Inherit ColdSpring Configuration</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/4/16/MachII-Modules-Dont-Automagically-Inherit-ColdSpring-Configuration</link>
				<description>
				
				This is probably obvious to anyone who&apos;s spent time with Mach-II and ColdSpring, but I ran in to the issue the other day, spent about an hour missing the obvious, and thought I&apos;d post.

If you have a Mach-II module, are using ColdSpring to manage dependencies in the parent application, the Mach-II module won&apos;t automatically inherit the ColdSpring setup. I had begun work on a simple module that didn&apos;t have any of its own objects to be managed by ColdSpring but instead would exclusively use objects managed at the parent application level. So I went about setting up a simple &quot;home&quot; view which needed some data from an object managed by ColdSpring in the parent app, and made a &amp;lt;call-method&amp;gt; command to it. I received an error stating that the bean I was looking for couldn&apos;t be found.

&quot;Well that&apos;s not right,&quot; I thought. &quot;I know the bean is in the parent app and other parts of the application are calling it just fine.&quot; After an hour or so of debugging, thinking that someone had broken the object in the latest build of the application, and getting a little annoyed, it dawned on me that I had never set up the ColdSpring property in this child module. Without the ColdSpring property being defined in the module, Mach-II had no idea how to call the bean I had specified in the  &amp;lt;call-method&amp;gt; command.

So if you are creating a module that has no ColdSpring-managed objects of its own, but do want to use ColdSpring-managed objects in the parent application, you still have to set up a basic ColdSpring Mach-II property in your module, and point it to an (essentially) empty ColdSpring config file. Your ColdSpring config file can look like this:

&lt;code&gt;
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans&gt;
&lt;/beans&gt;
&lt;/code&gt;

Once that is in place (and as long as you also define the parentBeanFactoryScope in your module&apos;s ColdSpring property CFC), your module will have access to all the ColdSpring managed objects in the parent application. 
				</description>
				
				<category>Mach-II</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Fri, 16 Apr 2010 13:01:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/4/16/MachII-Modules-Dont-Automagically-Inherit-ColdSpring-Configuration</guid>
				
			</item>
			
			<item>
				<title>Yes, Apple Really Is Out to Obviate Flash, But They Do Listen to Customers (Sometimes)</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/4/9/Yes-Apple-Really-Is-Out-to-Obviate-Flash-But-They-Do-Listen-to-Customers-Sometimes</link>
				<description>
				
				If you haven&apos;t heard, John Gruber at Daring Fireball has the lowdown on &lt;a href=&quot;http://daringfireball.net/2010/04/iphone_agreement_bans_flash_compiler&quot;&gt;Apple&apos;s pointed attack on Adobe and Flash in particular in the iPhone 4.0 license agreement&lt;/a&gt;. The key point: Apple has basically banned the use of tools like the Flash -&gt; iPhone packager that is a key piece of Adobe&apos;s flagship Creative Suite 5, set to launch on April 12. The bits are finalized, the discs are being burned and pressed as I write this, and a marquee feature of the suite has just been rendered null and void by a change in Apple&apos;s licensing agreement.

While I&apos;m more on the HTML5/JavaScript side of the fence than the Flash side of the fence when it comes to building rich internet applications, there&apos;s a lot of great stuff that Flash can do that HTML5/JavaScript simply cannot. It&apos;s not just about video. It&apos;s about the &lt;em&gt;applications&lt;/em&gt; that can be built. For now and the foreseeable future, Flash makes it drop-dead easy to build multi-user, rich media applications. It&apos;s a shame that those apps won&apos;t be able to make it on to the iPhone, or the iPad.

While the change in the licensing agreement also affects Mono (.NET) -&gt; Objective-C and other similar converters, it seems like the result of the will of one very powerful and very gifted individual who has exercised his power to reshape the landscape of the Web. It&apos;s feels mean, but that&apos;s business sometimes, isn&apos;t it? (See Gruber&apos;s most recent post on the issue for &lt;a href=&quot;http://daringfireball.net/2010/04/why_apple_changed_section_331&quot;&gt;the business reasons (alas, logical) why Apple made this change.&lt;/a&gt;)

On that note, there was something that struck me in the iPhone 4.0 SDK announcements yesterday which I thought was interesting from a UI perspective: the inclusion of folders in the iPhone UI. 

While Apple&apos;s products (and team) are extraordinarily opinionated, and those opinions are rigorously thought through, I found it surprising that an &quot;old&quot; desktop metaphor found its way back in to the iPhone/iPad UI. With &lt;a href=&quot;http://www.iterateme.com/blog/index.cfm/2010/1/31/Why-the-Mac-OS-X-107-UI-Will-be-the-iPad-UI&quot;&gt;Apple&apos;s very clear attempt to break from the desktop UI of files and folders in the iPad&lt;/a&gt;, and their reluctance to introduce any kind of hierarchical organizational system in to the iPhone SDK in previous iterations, the return of folders was surprising.

My guess is that folders returned for a very simple reason: it was the choice that made the most sense to their users. While Apple may appear arbitrary and capricious, they listen very, very carefully to their users when it comes to designing the experience. They probably iterated through a number of organizational ideas and most likely came back, time and again, to a simple, obvious, universally understood idea: the folder. Rather than forcing something new and unfamiliar to most (ie; stacks), they said &quot;Simple and already understood, if not radical and new.&quot;

So Apple does listen to their customers. Sort of. Sometimes. 
				</description>
				
				<category>Apple</category>				
				
				<pubDate>Fri, 09 Apr 2010 08:06:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/4/9/Yes-Apple-Really-Is-Out-to-Obviate-Flash-But-They-Do-Listen-to-Customers-Sometimes</guid>
				
			</item>
			
			<item>
				<title>Bug with Multiple &amp;lt;cffileupload&amp;gt; Controls and Different onComplete Handlers</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/3/10/Bug-with-Multiple-ltcffileuploadgt-Controls-and-Different-onComplete-Handlers</link>
				<description>
				
				A co-worker of mine has been bashing her head against a wall in recent days trying to figure out why a view with multiple &amp;lt;cffileupload&amp;gt; controls wasn&apos;t behaving properly. No matter what she did, a page with multiple &amp;lt;cffileupload&amp;gt; controls that also specified a different onComplete handler for each control always caused the last onComplete handler to be fired. She even made sure to have unique names for each file upload control.

It turns out that this is a completely reproducible bug in ColdFusion 9. Here&apos;s how you can replicate this bug:

&lt;code&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
	&lt;title&gt;cffileupload Bug Test&lt;/title&gt;
	&lt;script language=&quot;javascript&quot;&gt;
&lt;!--
	function uploadOneDone() {
		alert(&quot;uploadOneDone called&quot;);
	}
	
	function uploadTwoDone() {
		alert(&quot;uploadTwoDone called&quot;);
	}
//--&gt;
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;Upload One, calls uploadOneDone() when finished.&lt;/p&gt;
&lt;p&gt;&lt;cffileupload url=&quot;upload.cfm&quot; name=&quot;uploader1&quot; onComplete=&quot;uploadOneDone&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Upload Two, calls uploadTwoDone() when finished.&lt;/p&gt;
&lt;p&gt;&lt;cffileupload url=&quot;upload.cfm&quot; name=&quot;uploader2&quot; onComplete=&quot;uploadTwoDone&quot; /&gt;&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;
&lt;/code&gt;

You&apos;ll need a file called upload.cfm in the same directory as this test page. It can be as simple as:

&lt;code&gt;
&lt;cffile action=&quot;upload&quot; destination=&quot;#ExpandPath(&apos;.&apos;)#&quot; nameconflict=&quot;makeunique&quot;/&gt;
&lt;/code&gt;

Upload a file using the first uploader on the page. Here is the result you&apos;ll get:

&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;/blog/images/posts/cffileuploadOnCompelteBug.png&quot; width=&quot;500&quot; height=&quot;380&quot; alt=&quot;Results from cffileupload onComplete bug&quot; border=&quot;1&quot;&gt;&lt;/p&gt;

The last onComplete handler is fired, no matter how many of the controls are added to the page.

Maybe we&apos;re doing something wrong here, and if we are, I&apos;d love to know. In the meantime, I&apos;ve opened this as &lt;a href=&quot;http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html#bugId=82396&quot;&gt;bug #82396 in the ColdFusion bug tracker&lt;/a&gt;. Feel free to vote for it! 
				</description>
				
				<category>ColdFusion</category>				
				
				<pubDate>Wed, 10 Mar 2010 09:35:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/3/10/Bug-with-Multiple-ltcffileuploadgt-Controls-and-Different-onComplete-Handlers</guid>
				
			</item>
			
			<item>
				<title>Mach-II Call Method Command, How Do I Love Thee?</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/2/19/MachII-Call-Method-Command-How-Do-I-Love-Thee</link>
				<description>
				
				Now that &lt;a href=&quot;http://www.mach-ii.com/index.cfm/go/blog:showEntry/entryId/DA42ECE6%2DA834%2DA779%2DC42C698CA7FBF691/&quot;&gt;Mach-II 1.8 is out&lt;/a&gt;, I figured I&apos;d write a little bit about one of my favorite new features of the release, the &amp;lt;call-method&amp;gt; command.

Here&apos;s the problem that this new feature is designed to solve:

In a well-designed Mach-II application, you don&apos;t want to have a lot of business logic in your &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/IntroToListeners&quot;&gt;listeners&lt;/a&gt;. As a result, a lot of the methods in Mach-II listeners wound up being simple pass-throughs to a method in the service layer. This was repetitive, and tedious. Here&apos;s an example:

&lt;code&gt;
&lt;cffunction name=&quot;getAllUsers&quot; access=&quot;public&quot; output=&quot;false&quot; returntype=&quot;query&quot;&gt;
     &lt;cfargument name=&quot;event&quot; type=&quot;MachII.framework.Event&quot; required=&quot;yes&quot; /&gt;
     &lt;cfreturn variables.userService.getAllUsers() /&gt;
&lt;/cffunction&gt;
&lt;/code&gt;

We had to write a function that simply called a service layer method and returned the results. It&apos;s not hard to do. It is, however, clutter.

The &amp;lt;call-method&amp;gt; command eliminates the need for these kinds of placeholder method calls in your listener. Now you can do this in your Mach-II XML configuration file:

&lt;code&gt;
&lt;call-method bean=&quot;userService&quot; method=&quot;getAllUsers&quot; resultArg=&quot;qryAllUsers&quot; /&gt;
&lt;/code&gt;

The &quot;bean&quot; referenced in this tag is a &lt;a href=&quot;http://www.coldspringframework.org/&quot;&gt;ColdSpring&lt;/a&gt;-managed bean that has already been auto-wired by the &lt;a href=&quot;https://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/UsingColdSpringWithMach-II&quot;&gt;ColdSpring property in Mach-II&lt;/a&gt;. So this feature only works if you are also using ColdSpring (and &amp;mdash; I&apos;ve said it many times before &amp;mdash; if you&apos;re not using ColdSpring or some other IoC container in your ColdFusion applications, you&apos;re costing yourself time and money.) 

By using the &amp;lt;call-method&amp;gt; command, you&apos;ve turned four lines of code into one. Not bad!

What if your service layer methods require arguments to be passed to them? That&apos;s easy, and Mach-II handles this.

&lt;code&gt;
&lt;call-method bean=&quot;userService&quot; method=&quot;getUser&quot; args=&quot;${event.userID}&quot; resultArg=&quot;user&quot; /&gt;
&lt;/code&gt;

The args attribute of the &amp;lt;call-method&amp;gt; command can take single or multiple, comma-separated values, or even an argument collection structure. 

But what&apos;s the ${ } syntax? That&apos;s the expression language syntax that&apos;s built in to Mach-II. This feature arrived in &lt;a href=&quot;https://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/WhatsNewInMachII1.5&quot;&gt;Mach-II 1.5&lt;/a&gt; under the name &quot;Bindable Property Placeholders,&quot; and has evolved since then and is even more useful. It allows you to provide variables evaluated at runtime within the Mach-II configuration file. You can even provide default values in case the variable you&apos;re looking for in the expression doesn&apos;t exist (ie; ${event.userID:0}). So in the example above, it&apos;s going to to pass the result of evaluating event.userID (getting the value of the userID variable in the current event) to the userService.getUser() method.

I&apos;m using the &amp;lt;call-method&amp;gt; command in my latest project using 1.8. It&apos;s saving me time, makes the event flow as defined in the Mach-II XML config file clearer, and eliminates a duplicate layer of abstraction in the app. 

The official &lt;a href=&quot;https://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/MachII1.8CallMethodCommand&quot;&gt;documentation for the &amp;lt;call-method&amp;gt; command&lt;/a&gt; can be found in the Mach-II wiki. 
				</description>
				
				<category>Mach-II</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Fri, 19 Feb 2010 10:34:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/2/19/MachII-Call-Method-Command-How-Do-I-Love-Thee</guid>
				
			</item>
			
			<item>
				<title>Why the Mac OS X 10.7 UI Will be the iPad UI</title>
				<link>http://www.iterateme.com/blog/index.cfm/2010/1/31/Why-the-Mac-OS-X-107-UI-Will-be-the-iPad-UI</link>
				<description>
				
				I don&apos;t work at Apple. I have absolutely no evidence for this. This is pure speculation, but after processing the iPad announcement and the vortex of commentary about the iPad, I had an idea, and wanted to write it out.

The next major version of the Mac OS (10.7, or maybe 11) will likely adopt the iPad UI as its default UI. Here&apos;s why:

First, if you haven&apos;t read Steven Frank&apos;s commentary about &lt;a href=&quot;http://stevenf.tumblr.com/post/359224392/i-need-to-talk-to-you-about-computers-ive-been&quot;&gt;Old vs. New World Computing&lt;/a&gt;, you should. It strongly influenced my thought path. Steven makes some excellent points about customer expectations when it comes to &quot;new world&quot; computing.

Apple has made it very clear that they are becoming a mobile computing company. The company derives a majority of its revenue from iPods, iPhones, and laptops. Revenue from desktop sales accounts for less than a quarter of their overall revenue. The biggest area of growth they&apos;ve had (and are going to have) is in the mobile sector. This is going to influence their overall direction, even when it comes to their &quot;crown jewel&quot;: the Mac OS. Millions more people use iPods (including the Touch) and iPhones than Mac desktops and laptops. Millions of people have probably switched to the Mac due to their very positive experience with the iPod/Touch or iPhone (the &quot;halo effect&quot; as business analysts have called it), and that&apos;s the &quot;Apple experience&quot; that they are used to.

The iPhone OS was/is a variation on the Mac OS. It carried a similar design aesthetic and even some of the same basic iconography (Safari, Mail) that the desktop OS used. As the iPhone and its SDK have exploded on to the computing scene, I&apos;ve heard many people say (or write, or tweet) that &quot;it sure would be nice if you could [insert some iPhone capability] on the Mac too.&quot; Functionality may be a driver for iPhone -&amp;gt; Mac OS UI adoption, but I don&apos;t think that&apos;s it. I think it&apos;s about the experience.

The iPhone/Touch/iPad UI is super simple. You touch (essentially click) on something, and it responds. There are few, if any menus. You do one thing at a time and when you&apos;re done with one task, you move on to the next. It&apos;s hard to get lost in the iPhone UI. There are no files, no file structures, no antiquated, computing-device-from-1980-centric notions of how to get things done.

&lt;blockquote&gt;
A small detour: the iPad isn&apos;t for you, Person in the Software/Hardware/Web Application Development industry. I think that&apos;s a huge point that most of the analysts, pundits and commentators on the iPad this week missed. It&apos;s not a device that&apos;s going to replace your desktop/laptop with your 200 programs that you switch between at any given time to build the next Facebook. It&apos;s a device built for my Mom. Or your Mom. It&apos;s a device built for a 12 year-old kid who wants to connect and communicate in the very simple ways that IM, Facebook and SMS allow us to communicate while they watch TV, or sit on the bus, or are hanging out with friends. It&apos;s for people who don&apos;t care about a multitasking OS, or that it doesn&apos;t support real 720/1080p video (do you think they know what that means?), or &amp;mdash; here comes the big one &amp;mdash; that it doesn&apos;t support Flash.

&lt;blockquote&gt;
A detour from the detour: I miss Flash on my iPhone. I would like to see it on the iPad. But it&apos;s not going to happen. Ever. Apple has no business interest in making Flash run on the iPhone/Touch/iPad. &lt;a href=&quot;http://daringfireball.net/2010/01/apple_adobe_flash&quot;&gt;John Gruber clearly explains why&lt;/a&gt;. And the average customer won&apos;t think that there&apos;s something wrong with the iPhone/Touch/iPad. They&apos;ll think there&apos;s something wrong with your Web site. More than a decade of using the Web has taught users that when something goes wrong on a Web site, or something doesn&apos;t work on a Web site, it&apos;s the Web site&apos;s fault, not their computer. Not their iPhone. Their iPhone just works.
&lt;/blockquote&gt;
&lt;/blockquote&gt;
Back to the topic at hand.

If you buy an iPhone (or iPad) and you decide to move to a Mac from Windows, you&apos;ve got another UI to learn. You learned the Windows UI, then you learned how to use the iPhone (or iPod Touch) UI, and now you&apos;ve got a third one to learn. And that can be scary, and an annoyance, and a big time sink, and maybe a reason that you won&apos;t switch to a Mac desktop or laptop.

But if the UI you see when you buy that Mac laptop or desktop looks a whole lot like the UI you already know (and probably really like) on the iPhone/Touch/iPad, switching suddenly seems a lot less scary.

But what about the desktop? The Finder (or file system)? What about the Dock? What about having iTunes and Mail and iPhoto and Safari and iChat all open at the same time and clicking on their respective windows to quickly switch between them?

One of the major areas of frustration for most users in modern desktop/laptop computing is the file system. I know this may sound absurd, but as someone who works directly with users in face-to-face training classes (and online doing the occasional support that anyone who has a job in computing technology eventually does), users still, after 20+ years, don&apos;t get how a file system works and they don&apos;t get how to organize files, and, most importantly, to find them once they&apos;ve saved them somewhere. This isn&apos;t just a Mac OS thing. This applies to Windows as well (perhaps even more so in the Windows word, but that&apos;s just me being a Windows basher). Beyond storing everything in the default location provided by the OS (or on the Desktop, because that&apos;s where a user can &quot;see&quot; their files), most users are utterly baffled by the complexity of a file system. If the computer could just figure it out for them and find the file when they needed the file, they&apos;d be so much happier. Why do people send and store everything via email? Because it&apos;s really simple to find what they need using their mail client&apos;s search functionality. 

&lt;blockquote&gt;
(Please note that I&apos;m not saying that you, dear reader, aren&apos;t smart enough to figure out the file system. If you&apos;re reading this rather unknown blog that mostly focuses on Web application development in ColdFusion, then you probably know more than your average user about computers and file systems.)
&lt;/blockquote&gt;

Apple has &lt;a href=&quot;http://www.roughlydrafted.com/2010/01/29/apple-reinventing-file-access-wireless-sharing-for-ipad/&quot;&gt;already taken steps in the iPad (iPhone SDK) to mask the complexity of the file system&lt;/a&gt; by having documents for a given application stored in the installation directory for the application. According to the article in RoughlyDrafted Magazine: &quot;Documents copied to the app&apos;s shared folder will be graphically presented by the app when it launches, sparing users from having to figure out where to look for their document files and avoiding any need to sort through different kinds of documents.&quot; Sounds like Apple has taken a giant step towards masking the complexity of the file system to me.

It would be easy for Apple to offer a real, separate, standalone Finder app (not the one that still acts as the Mac OS desktop) in an iPad UI-based desktop/laptop OS for those times that anyone needs to navigate the hierarchy of the file system. If you want to get under the hood, you still could via the Finder app or the Terminal app, just like you do now. 

(If you reflect on it a bit, you can see the direct, clear line between the idea of the iPhone/Touch/iPad UI and the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mac_OS_&quot;&gt;Simple Finder from Mac OS 8&lt;/a&gt;.)

OK, so what about multitasking then? One of the great things about computers is that you can be working in 7 different programs at once if you need to and you can switch between them super easily.

When was the last time you watched (not just assumed) how a non-computer/software development-centric user gets things done? Most people use their computers for one task at a time. I check my email. I search for this thing on Google. I write this in Word. I play WoW. Most users focus on a single task in a single interface and then move on to another task in another interface. There is little to no need to jump between applications to get their work done. Google is taking this idea to its logical end by making the Chrome OS run a single application: the Web browser. Everything you could/should need to do can be accomplished via the Web browser, so why have any other applications in the OS?

&lt;blockquote&gt;
(And, again, as a side note for the software developers reading this: think about Eclipse. Part of the success of Eclipse as a platform is the ability to add plug-ins of myriad scale and functionality to Eclipse so that it can do just about anything you want from a single interface, in a perspective that helps you focus on the task at hand. Isn&apos;t that what tools like Mylyn are all about?)
&lt;/blockquote&gt;

It would be trivial, in an iPad-based UI, for Apple to allow for multiple processes so that you could listen to iTunes while you surfed the Web in Safari, or receive incoming IMs or Facebook notifications while you read your email. That&apos;s not a problem and wouldn&apos;t be an issue in an iPad-based Mac OS 10.7 UI. Apple can keep the multitasking nature of the OS while masking the complexity of a multitasking environment behind a simple, one-app-at-a-time view.

Does the idea a single, full-screen view of a single application at any given time sound familiar? An operating system made by a company based in Redmond, Washington, adopted this model of computing years ago. When an application opens in Windows, the default view is for the application to expand to fill the screen. You can switch to other applications as needed (or even make them smaller so you can see multiple applications at once, like you can on the Mac OS). You are, however, focusing on a single application at any given time if you go with all of the defaults. Yes, the Start menu, like all menus, is an exception. But this is the desktop window UI that a majority of users have come to learn and expect.

One of the things I see switchers from Windows to the Mac struggle with is the concept of multiple application windows being open and visible at once. If you&apos;ve used Windows for a long time, you expect that when you open Word, it&apos;s going to fill the screen. Not so on the Mac. Most windows don&apos;t fill the screen (iMovie and other non-linear video editors being an exception). There are floating palettes. There&apos;s a whole bunch of stuff that quickly piles up in a single window and it&apos;s easy to accidentally click on the wrong window and bring up an application that you don&apos;t want to work with at the moment.

Apple isn&apos;t shy about stealing from Redmond when it needs to. If it would make it easier for switchers to actually make that switch if the single-application-visible approach taken by default by Windows became the standard, out-of-box experience on Windows, that&apos;s a compelling argument for making that change. And that&apos;s how the iPad UI works.

Apple has a business interest in updating the Mac OS (and the iPhone SDK) on a regular basis. It sells. It sells hardware. It helps them to remain competitive and gives them yet another opportunity to dance circles around the folks in Redmond. OS additions like 64-bit computing and offloading computing power to the GPU sure sound nice if you  know what they mean, but it&apos;s the UI changes that are the big ticket items, the big showpieces, and the big drivers for most consumers of an OS. Saying that &quot;we&apos;ve left the UI from 1984 behind and have made a true OS for the mobile Internet era&quot; would be a big ticket item for Apple. (If it was actually, deeply tied to the Internet and cloud storage.)

Apple is, at its core, a company about the user experience. From the original Macintosh (making the arcane art of the command line go away in favor of a GUI) to the genius of using your finger as the primary interaction point between you and your computing device, Apple is about making the user experience simple and elegant. Apple doesn&apos;t care about offering 5,437 features in a single device. They care about offering 10 things that &lt;em&gt;really&lt;/em&gt; matter, are core to getting the primary tasks of the device completed, and making those 10 things work flawlessly. If you&apos;ve used the iPhone or iPod Touch, it&apos;s definitely simple and elegant. It just works. It&apos;s a really nice experience. It&apos;s the epitome of the &quot;New World&quot; computing that Steven Frank writes about. Why wouldn&apos;t Apple want to capitalize on that to make a simple, elegant, seamless experience from one of their devices to another?

I&apos;ve left out just a few minor details, like how file storage would work in an OS that masks the file system and directory heirarchy as much as possible, and how cloud integration might allow the OS to become a true &quot;OS for the Internet&quot; (see &lt;a href=&quot;http://www.appleinsider.com/articles/09/12/07/apples_lala_purchase_could_bring_browser_access_to_itunes_content.html&quot;&gt;Apple&apos;s acquisition of Lala&lt;/a&gt;, their new &lt;a href=&quot;http://www.macrumors.com/2009/08/18/apples-north-carolina-data-center-to-focus-on-cloud-computing/&quot;&gt;billion dollar data center in North Carolina&lt;/a&gt;, and our eternal hopes for a revamped MobileMe service as indicators), but this covers the basics of my hypothesis. Enjoy! 
				</description>
				
				<category>Apple</category>				
				
				<pubDate>Sun, 31 Jan 2010 08:52:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2010/1/31/Why-the-Mac-OS-X-107-UI-Will-be-the-iPad-UI</guid>
				
			</item>
			
			<item>
				<title>Lessons Learned in Making Many Mach-II Modules Out of Standalone Apps</title>
				<link>http://www.iterateme.com/blog/index.cfm/2009/12/30/Lessons-Learned-in-Making-Many-MachII-Modules-Out-of-Standalone-Apps</link>
				<description>
				
				This entry is about a month overdue, but given the holidays and Getting Stuff Done (SM) at work, it&apos;s been delayed.

As I mentioned in my first posting in the series, I&apos;m in the process of converting a bunch of standalone Mach-II apps in to modules inside of  a new, monolithic application. It&apos;s been a surprisingly smooth process, thanks to the tools that the Mach-II framework gives us to work with. Most of the bumps along the way have been related to bad software design practices in some of the oldest apps that I&apos;ve created, and continuing, after many years building Web applications, to do dumb things like hardcoding URLs and other strings which will change when converting the app to a module (or moving the app to a different server).

Here are a few key lessons I&apos;ve learned:

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use BuildURL and the View Tag Library generously.&lt;/strong&gt; One of the major time sinks I&apos;ve had to endure in this process is changing all of the links and constructed URLs in the apps-to-modules. If you&apos;re using Mach-II and still writing &amp;lt;a href&amp;gt;s in your views, you&apos;re throwing money out the window. Sooner or later, those URLs are going to change, and you&apos;re going to have to rewrite them. &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/URLManagementFeatures&quot;&gt;BuildURL&lt;/a&gt; and the &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/MachII1.8SpecificationViewTagLib&quot;&gt;View Tag Library&lt;/a&gt; encapsulate the creation of URLs/links in your views so that when you change servers (or need to roll out a new version of a module in a different directory), you do very little (to no) work to make the URLs/links all update nicely. And, yes, you can use them to create links in your inline JavaScript (if you use inline JavaScript).&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid redundancies in your ColdSpring configuration files.&lt;/strong&gt; If you&apos;re going to share functionality across modules and you manage your object dependencies with ColdSpring, you&apos;re going to run in to instances where you define a bean multiple times in multiple ColdSpring configuration files. This is a really common situation. If you have a userService, for example, you&apos;re probably going to refer to this userService throughout the modules in your application. It&apos;s easy to define that userService in each of the ColdSpring configuration files in each of the modules that uses the userService, but don&apos;t. Simply define the userService bean in the ColdSpring configuration file at the top level of the application, and then if you inherit beans defined in the parent (top level) app as &lt;a href=&quot;http://www.iterateme.com/blog/index.cfm?mode=entry&amp;entry=217C9B3F-FC55-241C-4003251CB14DB2F7&quot;&gt;discussed in this post&lt;/a&gt;, you have access to that userService in your module. You don&apos;t need to define it again, and doing so is wasteful, and may lead to subtle (or not so subtle) issues when the a new version of the service is rolled out in the parent but your child is using an old version of the service because it&apos;s been define that way in the child ColdSpring config file. If your module needs a specific version of the service (eg; it needs to keep an old version for compatibility with something else), you can define it in the child ColdSpring config file as needed.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid per-module session objects.&lt;/strong&gt; This is a really easy trap to fall in to if you are porting existing Mach-II applications to modules inside a new, larger application. Most of your existing apps will have information stored in the session scope. It&apos;s tempting to keep your perfectly fine code as-is and just create new session variables as needed in each of your apps-to-modules. The problem here is that if you&apos;re creating new session variables in 7 or 15 or 22 modules, you&apos;re going to start to eat up memory and, more importantly, you&apos;re going to have to try to track down why things are going wrong in 7 or 15 or 22 session variables rather than in a single location. It&apos;s just bad form to &lt;em&gt;not&lt;/em&gt; encapsulate everything you need in the session scope in a single variable created and managed at the top layer of your application. In all likelihood, all those redundant session variables generated in your modules largely contain the same information &amp;mdash; userIDs, user objects, security or role-permission information, and the like. Managing this in one place makes a heck of a lot more sense than spreading it out in to each of your modules.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handle exceptions and errors at the main app level.&lt;/strong&gt; As with redundant bean definitions or per-module session objects, per-module exception and error handling is most often redundant. While there may be cases where you want to handle an exception in a special way in a module, there&apos;s no good reason to have different exception or error views in each module. Provide a consistent way of handling errors and exceptions for the developers behind the app and a consistent experience for the people using the app. If you want to do some module-specific handling of errors (to try to recover, to log something specific to the module, etc.), you can do this in your module&apos;s Mach-II XML config file:&lt;br/&gt;&lt;br/&gt;
&lt;code&gt;
&lt;event-handler event=&quot;exception&quot;&gt;
     &lt;filter name=&quot;tryToRecoverFromExceptionFilter&quot; /&gt;
     &lt;-- OR --&gt;
     &lt;notify listener=&quot;someListener&quot; method=&quot;doSomeErrorProcessing&quot; /&gt;
     &lt;-- FINALLY --&gt;
     &lt;announce module=&quot;&quot; event=&quot;exception&quot; copyEventArgs=&quot;true&quot;/&gt;
&lt;/event-handler&gt;
&lt;/code&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Get rid of the extra junk.&lt;/strong&gt; Not using all the plugin points you stubbed out in your plugins? (Or, in my case, left in there because you copied from the samplePlugin.cfc that came with the framework?) Get rid of them. No longer using that sessionFacade.cfc because you&apos;re managing your session objects centrally? Get rid of it. Get rid of everything you&apos;re not using. It&apos;s good practice and will make things cleaner and easier to understand for the poor sap who has to work on the app your absence.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;

So that&apos;s it for this series. I have to give major props to the Mach-II team for making it so easy to convert existing Mach-II applications to Mach-II modules. It&apos;s made this big project so much easier. 
				</description>
				
				<category>Mach-II</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Wed, 30 Dec 2009 09:39:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2009/12/30/Lessons-Learned-in-Making-Many-MachII-Modules-Out-of-Standalone-Apps</guid>
				
			</item>
			
			<item>
				<title>Mach-II Modules and Views</title>
				<link>http://www.iterateme.com/blog/index.cfm/2009/11/30/MachII-Modules-and-Views</link>
				<description>
				
				It looks like I&apos;m going to spend another Monday morning writing about Mach-II modules. In this entry in the series, I&apos;m going to look at how your CFML-based views are affected by the Mach-II module structure.

Mach-II provides a lot of convenience methods for handling views. In Mach-II 1.8, there&apos;s a whole &lt;a href=&quot;http://www.mach-ii.com/index.cfm/go/blog:showEntry/entryId/41CE16F0%2DEC26%2DC39B%2D4A9315BA9DA78C19/&quot;&gt;new set of tag libraries&lt;/a&gt; which make tying your views to other actions in a Mach-II application even simpler. Of particular interest are the &lt;a href=&quot;https://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/MachII1.8SpecificationFormTagLib&quot;&gt;&amp;lt;form&amp;gt;&lt;/a&gt; and  &lt;a href=&quot;https://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/MachII1.8SpecificationViewTagLib&quot;&gt;&amp;lt;view&amp;gt;&lt;/a&gt; tag libraries as they make dealing with mundane tasks like binding form fields to event objects and creating links simpler and more flexible under the Mach-II framework. Prior to Mach-II 1.8, there were the &lt;a href=&quot;https://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/WhatsNewInMachII1.5&quot;&gt;BuildURL() and BuildURLToModule() methods&lt;/a&gt;, which were your biggest friends in building links within and between modules in a Mach-II app.

I realize that not everyone likes to have a framework write their URLs for them. There are issues of convention, framework agnosticism, SEO optimization, and individual style that can and often should be factored in. However, if you&apos;re using Mach-II modules or Mach-II SES URL rewriting, or the new &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/MachII1.8SESImprovements&quot;&gt;routes support in Mach-II 1.8&lt;/a&gt;, it would be quite unwise to write URLs on your own. I&apos;d argue that as you&apos;ve made the investment in the framework to begin with, you should let the framework generate your URLs for you via its various convenience methods in all cases. If you ever switch domains or even move the base URL path of your application or need to swap one module for another, changing a single value in your Mach-II XML config file is going to be a lot faster (and a lot less error prone) than doing a search and replace on every &amp;lt;a href&amp;gt; in your code base.

(As a side note, I&apos;ve had issues with outputting BuildURL() calls within JavaScript blocks, and did use that as an exception to the above rule. However, the new &lt;a href=&quot;https://greatbiztoolsllc-trac.cvsdude.com/mach-ii/ticket/178&quot;&gt;buildUnescapedUrl() function introduced in Mach-II 1.8&lt;/a&gt; eliminates that exception.)

&lt;strong&gt;Using BuildURL() and BuildURLToModule()&lt;/strong&gt;

By using BuildURL() and, more relevant to this post, BuildURLToModule(), you let Mach-II handle the writing of your &amp;lt;a href&amp;gt; tags. These functions are available in views only, and not inside plugins, filters, or listeners. If you use Mach-II modules, you&apos;re going to want to use BuildURLToModule() over BuildURL() in most cases. Here&apos;s why:

&lt;ul&gt;
&lt;li&gt;BuildURLToModule() ensures that the module is preprended to the event name in the resulting URL. This ensures that the user is routed to the right module when the event is requested.&lt;/li&gt;
&lt;li&gt;BuildURLToModule() allows for an empty module name in the module argument of the function. This lets you write events which point to the main/parent application and forces the request to go to the main/parent application.&lt;/li&gt;
&lt;/ul&gt;

If you just use BuildURL(), Mach-II is going to assume that you want an event in the same/current module. This works fine if you are at the top level of your application, in the main/parent portion of the application. This doesn&apos;t work so well if you&apos;re inside a module. For example, if you have an event called &quot;logout&quot; tied to a &quot;Logout&quot; link and you are inside a module and a user clicks on the &quot;Logout&quot; link, BuildURL() is going generate a  link that looks for an event called &quot;logout&quot; &lt;strong&gt;in the current module&lt;/strong&gt;. As the logout event is (probably) defined in the main/parent application, Mach-II won&apos;t be able to find the event in the current module, and an exception will be thrown.

As a result, it&apos;s a good idea to use BuildURLToModule() instead of BuildURL() in both the parent &lt;em&gt;and&lt;/em&gt; child (module) application views. This way, you ensure that the user is being routed to the right event in the right module, even if it&apos;s the default/parent module. This is my personal preference, and not an official guideline of Team Mach-II.

&lt;strong&gt;Using the &amp;lt;view&amp;gt; Library&lt;/strong&gt;

The &amp;lt;view:a&amp;gt; tag is a handy way to let Mach-II write your &amp;lt;a href&amp;gt; links. It does much of what the BuildURL() and BuildURLToModule() functions have done for some time now, only in a simpler and more elegant wrapper. Now that I&apos;m using Mach-II 1.8 to build my applications (and for this particular, module-heavy project), I prefer it to BuildURL() for generating &amp;lt;a href&amp;gt;s. I still use BuildURLToModule() when I&apos;m not generating a &amp;lt;a href&amp;gt; tag.

There are &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/MachII1.8SpecificationViewTagLib#TheaTag&quot;&gt;lots and lots of options when using the &amp;lt;view:a&amp;gt; tag&lt;/a&gt;, but the basic format of generating a link is as follows:

&lt;code&gt;
&lt;view:a module=&quot;blog&quot; event=&quot;showEntry&quot; p:entryId=&quot;456&quot;&gt;&lt;/view:a&gt;
&lt;/code&gt;

You simply specify the event name in the event attribute, the module name in the module attribute, and any key/value pairs you want to add to the link in the p attribute. If you have multiple key/value pairs you want to add, just put multiple p attributes in the tag, as follows:

&lt;code&gt;
&lt;view:a module=&quot;blog&quot; event=&quot;showComments&quot; p:entryId=&quot;456&quot; p:commentID=&quot;89&quot;&gt;&lt;/view:a&gt;
&lt;/code&gt;

You can put CF variable names in lieu of static values, or use the expression language syntax available in Mach-II to generate the values:

&lt;code&gt;
&lt;view:a module=&quot;blog&quot; event=&quot;showComments&quot; p:entryId=&quot;${event.entry.entryID}&quot; p:commentID=&quot;89&quot;&gt;&lt;/view:a&gt;
&lt;/code&gt;

Again, you should provide a blank value for the module attribute if you want the link to point to an event in the main/parent application. This ensures that Mach-II looks for an event in the main/parent application and not in the current module.

&lt;strong&gt;Using the &amp;lt;form&amp;gt; Library&lt;/strong&gt;

When it comes to generating form action attributes, the &amp;lt;form&amp;gt; tag library works just like the &amp;lt;view:a&amp;gt; tag. An example:

&lt;code&gt;
&lt;form:form actionEvent=&quot;createEntry&quot; actionModule=&quot;blog&quot;&gt;
&lt;/code&gt;

It&apos;s very unlikely you&apos;d be doing a form post from a module back to the parent/main application. As a matter of fact, I can&apos;t think of a good use for it. It&apos;s still a good idea to specify the module in which the event exists via the actionModule attribute, however, to ensure that the link is always written properly.

There&apos;s &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/MachII1.8SpecificationFormTagLib&quot;&gt;lots of documentation for the &amp;lt;form&amp;gt; tag library&lt;/a&gt;, so please review it to see what it&apos;s capable of. Binding, for example, is just plain useful and cool.

&lt;strong&gt;Reducing Most of the Above to a Single Point&lt;/strong&gt;

The key point is this: no matter how you write your URLs, always make sure that a module (or an empty string for a module) is specified. This will ensure that event requests are routed to the right place. Start doing this when you begin to build your views, and you&apos;ll find it saves you time down the road when you&apos;re connecting everything. 
				</description>
				
				<category>Mach-II</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Mon, 30 Nov 2009 11:56:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2009/11/30/MachII-Modules-and-Views</guid>
				
			</item>
			
			<item>
				<title>Mach-II Modules and ColdSpring</title>
				<link>http://www.iterateme.com/blog/index.cfm/2009/11/23/MachII-Modules-and-ColdSpring</link>
				<description>
				
				Ah, &lt;a href=&quot;http://coldspringframework.org/&quot;&gt;ColdSpring&lt;/a&gt;. In my opinion, you&apos;re the bees&apos; knees. You&apos;re what makes managing object dependencies a breeze. You simplify and enable the development of object-oriented ColdFusion apps so much that you&apos;re core to most large-scale ColdFusion applications written in the last couple of years. The teams behind Mach-II, Model-Glue and ColdBox like you so much that they made you a key player in their framework stacks. I&apos;m not going to sell you on the virtues of ColdSpring any longer, so if you&apos;re not using it already, &lt;a href=&quot;http://coldspringframework.org/coldspring/examples/quickstart/&quot;&gt;start please&lt;/a&gt;.

The key to using ColdSpring in Mach-II modules is the super-fantastic &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/WhatsNewInMachII1.6#ColdSpringProperty&quot;&gt;ColdSpring property&lt;/a&gt; that comes bundled with Mach-II 1.6 (and later). You need to be using the ColdSpring property and &lt;em&gt;not&lt;/em&gt; the old ColdSpring plug-in which was available prior to Mach-II 1.6. I know that updating core infrastructure components like frameworks can be scary, but Team Mach-II has done a great job with making Mach-II backwards-compatible to the 1.1 version, so upgrading to take advantage of newer framework features shouldn&apos;t be too scary.

If you need to learn how to get the ColdSpring property working in your Mach-II application, please &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/UsingColdSpringWithMach-II&quot;&gt;review the documentation&lt;/a&gt;.

The key point about using ColdSpring in Mach-II modules is that you can both set up individual ColdSpring factories for each module in your application &lt;em&gt;and&lt;/em&gt; have access to a main, or parent, factory defined at the base level of your application. This is quite powerful for two reasons:

&lt;ol&gt;
&lt;li&gt;ColdSpring managed objects become specific to the module in which they are needed, and don&apos;t clutter up the rest of the application, and,&lt;/li&gt;
&lt;li&gt;Commonly used objects can be created at the main/parent application level and be re-used throughout the entirety of the application, as needed.&lt;/li&gt;
&lt;/ol&gt;

In order to use ColdSpring in a module, you need to create a ColdSpring property and define it in your Mach-II XML configuration file for the module:

&lt;code&gt;
&lt;mach-ii version=&quot;1.8&quot;&gt;
   &lt;!-- INCLUDES --&gt;
   &lt; includes&gt;
      &lt; include file=&quot;/myApp/modules/sampleMod/config/sampleMod-coldSpringProperty.xml&quot; /&gt;
   &lt;/includes&gt;

   ...listeners, events, plugins, etc...

&lt;/mach-ii&gt;
&lt;/code&gt;

The basic information you need to provide in your coldSpringProperty.xml file to use ColdSpring in a module is as follows:

&lt;code&gt;
&lt;mach-ii version=&quot;1.0&quot;&gt;
    &lt;properties&gt;
		&lt;property name=&quot;coldSpringProperty&quot; type=&quot;coldspring.machii.ColdspringProperty&quot;&gt;
			&lt;parameters&gt;
				&lt;parameter name=&quot;beanFactoryPropertyName&quot; value=&quot;serviceFactory&quot;/&gt;
				&lt;parameter name=&quot;configFile&quot; value=&quot;/path/to/my/coldSpringServicesFile.xml&quot;/&gt;			
				&lt;parameter name=&quot;configFilePathIsRelative&quot; value=&quot;false&quot;/&gt;
				&lt;parameter name=&quot;resolveMachIIDependencies&quot; value=&quot;true&quot;/&gt;
				&lt;parameter name=&quot;parentBeanFactoryScope&quot; value=&quot;application&quot;/&gt;
				&lt;parameter name=&quot;parentBeanFactoryKey&quot; value=&quot;serviceFactory&quot;/&gt;
			&lt;/parameters&gt;
		&lt;/property&gt;
    &lt;/properties&gt;
&lt;/mach-ii&gt;
&lt;/code&gt;

Here&apos;s what each parameter does:

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;beanFactoryPropertyName&lt;/strong&gt; &amp;mdash; This one isn&apos;t required, but you really should give your ColdSpring bean factory a name. You &lt;em&gt;must&lt;/em&gt; do this in the ColdSpring property XML file for your base application, for reasons I&apos;ll describe below.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;configFile&lt;/strong&gt; &amp;mdash; This is the path to the ColdSpring XML file for your module, in which ColdSpring-managed beans are defined. This one&apos;s required.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;configFilePathIsRelative&lt;/strong&gt; &amp;mdash; This lets Mach-II know if it should be using an absolute or relative path to find the ColdSpring XML file defined above. Defaults to false.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;resolveMachIIDependencies&lt;/strong&gt; &amp;mdash; This defaults to false, but if you plan on using the super-convenient &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/UsingColdSpringWithMach-II#UsingAutowirebyDependsAttribute&quot;&gt;Mach-II autowriring&lt;/a&gt; introduced in Mach-II 1.6, then this must be set to true, or nothing gets autowired in to your plugins, listeners, or filters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;parentBeanFactoryScope&lt;/strong&gt; &amp;mdash; Here&apos;s where you tie in the bean factory from your base/parent Mach-II application to your module. By setting this to true, you complete one half of the steps needed to pull in beans defined in the base application but that are used across your whole application. This merely defines the scope in which your parent bean factory is stored. That&apos;s most often going to be the application scope.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;beanFactoryPropertyName&lt;/strong&gt; &amp;mdash; The value provided here &lt;em&gt;must&lt;/em&gt; match the beanFactoryPropertyName value defined in your parent/base app. If it does, you&apos;ve completed the second half of the steps needed to pull in beans defined in the base application but that are used across your whole application.&lt;/li&gt;
&lt;/ul&gt;

So how does all of this work in practice?

I&apos;m not going to go in to how you define ColdSpring-managed beans in the ColdSpring XML file. That&apos;s all in the &lt;a href=&quot;http://coldspringframework.org/index.cfm/go/documentation&quot;&gt;ColdSpring documentation&lt;/a&gt;. I&apos;ll show you how you can use the beans defined in your base app in your module.

Let&apos;s say you have a userService that is defined in your base ColdSpring XML file. This is a pretty common scenario, as you&apos;ll most likely need that userService (for things like getting user information) throughout your application, and in all of your modules. Here&apos;s the userService defined in your base ColdSpring XML file:

&lt;code&gt;
&lt;beans&gt;
	&lt;bean id=&quot;userService&quot; 
		class=&quot;path.to.userService&quot;&gt;
		&lt;constructor-arg name=&quot;dsn&quot;&gt;
			&lt;value&gt;${dsn}&lt;/value&gt;
		&lt;/constructor-arg&gt;
	&lt;/bean&gt;

         ...more beans defined here...
&lt;/beans&gt;
&lt;/code&gt;

In your module&apos;s ColdSpring XML file, you can then utilize the userService like this:

&lt;code&gt;
&lt;beans&gt;
	&lt;bean id=&quot;reportingService&quot; 
		class=&quot;path.to.reportingService&quot;&gt;
		&lt;property name=&quot;userService&quot;&gt;
			&lt;ref bean=&quot;userService&quot;/&gt;
		&lt;/property&gt;
	&lt;/bean&gt;

         ...more beans defined here...
&lt;/beans&gt;
&lt;/code&gt;

&lt;strong&gt;You don&apos;t define the userService in your module&apos;s ColdSpring XML file.&lt;/strong&gt; Because you&apos;ve defined it in the parent/base app&apos;s ColdSpring XML file, and you set the parentBeanFactoryScope property to &quot;application&quot; (because that&apos;s where the parent bean factory is stored) and you set the beanFactoryPropertyName property to the same value as defined in the parent/base app&apos;s ColdSpring XML file, Mach-II&apos;s ColdSpring property is smart enough to figure out how to grab the userService and put it in the right place.

This is just one example. You can use as many beans from your parent/base app in your modules as you need. By defining commonly used beans in your parent/base app, you reduce your application&apos;s overall memory footprint and encourage good object reuse.

&lt;strong&gt;One Big Caveat&lt;/strong&gt;

There&apos;s one thing you really need to watch out for when using ColdSpring and Mach-II modules: bean name collisions. If you define a bean in your parent/base app called &quot;page&quot; and you also define a bean in your module ColdSpring XML called &quot;page,&quot; guess which one is going to get used in your module? I&apos;d recommend that you always using module-specific bean names for the beans defined in your module&apos;s ColdSpring XML file. This way, you can ensure that you&apos;re not going to run in to naming collisions.

&lt;strong&gt;A Few Other Options&lt;/strong&gt;

You can put the bean factory from your module back in to the parent scope if you need to utilize the module bean factory in the parent/base app. You may have bits of functionality encapsulated in a module that need to be utilized elsewhere in your application. For example, if you have a threaded discussion module, you may want to display the 10 most recent posts on your application&apos;s home page. As the functionality for doing this is already defined in a bean that is managed by the threaded discussion module&apos;s ColdSpring bean factory, you may want to use that bean in the parent/base application rather than defining it again in the parent/base application&apos;s ColdSpring XML file. 

To accomplish this, you need to add this one line to your module&apos;s ColdSpring property file:

&lt;code&gt;
&lt;parameter name=&quot;placeFactoryInApplicationScope&quot; value=&quot;true&quot;/&gt;
&lt;/code&gt;

This places the module&apos;s ColdSpring bean factory in the parent application&apos;s application scope. As explained in the &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/UsingColdSpringWithMach-II#ParentChildBeanFactoriesConfigurationforUsewithModules&quot;&gt;Mach-II documentation for the ColdSpring property&lt;/a&gt;, Mach-II appends the &lt;em&gt;name of the module&lt;/em&gt; to the beanFactoryPropertyName value when the module&apos;s ColdSpring bean factory is added to the parent&apos;s bean factory to avoid beans in the module overwriting those defined in the parent. Pretty smart stuff!

Finally, you can use ColdSpring in your module, but not worry about utilizing beans defined in the parent/base application at all. You lose some power and code-reuse, but you may have no good need to use the parent bean factory. In that case, just omit the parentBeanFactoryScope and parentBeanFactoryKey parameters from your module&apos;s ColdSpring property XML file, and you&apos;re good to go.

Whew! These entries are turning out to be longer than I expected. But there are more to come! 
				</description>
				
				<category>Mach-II</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Mon, 23 Nov 2009 11:32:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2009/11/23/MachII-Modules-and-ColdSpring</guid>
				
			</item>
			
			<item>
				<title>Mach-II and Module Config Files</title>
				<link>http://www.iterateme.com/blog/index.cfm/2009/11/16/MachII-and-Module-Config-Files</link>
				<description>
				
				In this installment of my mini-series on modules in &lt;a href=&quot;http://www.mach-ii.com/&quot;&gt;Mach-II&lt;/a&gt;, I&apos;m going to talk about the Mach-II XML config file for your module, how it relates to the parent (main application) Mach-II XML config file, and try to offer some tips on what should and should not go in your module&apos;s Mach-II XML config file.

Before I go any further, it&apos;s important that you understand the &lt;a href=&quot;http://www.iterateme.com/blog/index.cfm?mode=entry&amp;entry=DEC12E41-9170-55E7-0A9965A45A46B209&quot;&gt;context of this particular series&lt;/a&gt; on Mach-II modules and the fact that, for my specific purposes, I am not talking about building modules which are intended for drop-in deployment into any Mach-II app anywhere, like the fantastic &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/Dashboard&quot;&gt;Mach-II Dashboard&lt;/a&gt;. I&apos;m focusing on building modules that represent mini-applications operating under the auspices of a larger application. Examples of these modules would be a threaded discussion system in a larger community site, or an exam system in an online course site.

&lt;strong&gt;A Sample Module XML Config File&lt;/strong&gt;

Below is a really simple Mach-II XML config file for a module.

&lt;code&gt;
&lt;mach-ii version=&quot;1.8&quot;&gt;
	&lt;!-- INCLUDES --&gt;
	&lt; includes&gt;
		&lt; include file=&quot;/myApp/modules/sampleMod/config/sampleMod-coldSpringProperty.xml&quot; /&gt;
	&lt;/includes&gt;
	
	&lt;!-- PROPERTIES --&gt;
	&lt;properties&gt;
		&lt;property name=&quot;applicationRoot&quot; value=&quot;/myApp/modules/sampleMod/&quot; /&gt;
		&lt;property name=&quot;defaultEvent&quot; value=&quot;sampleModHome&quot; /&gt;
	&lt;/properties&gt;

	&lt;!-- LISTENERS --&gt;
	&lt;listeners&gt;
		&lt;listener name=&quot;simpleListener&quot; type=&quot;myApp.modules.sampleMod.model.simpleListener&quot; /&gt;
	&lt;/listeners&gt;
	
	&lt;!-- EVENT-FILTERS --&gt;

	&lt;!-- EVENT-HANDLERS --&gt;
	&lt;event-handlers&gt;
		&lt;event-handler event=&quot;sampleModHome&quot; access=&quot;public&quot;&gt;
			&lt;notify listener=&quot;simpleListener&quot; method=&quot;getRandomNumber&quot; resultArg=&quot;randomNumber&quot; /&gt;
			&lt;notify listener=&quot;simpleListener&quot; method=&quot;getHTTPString&quot; resultArg=&quot;httpAddress&quot; /&gt;
			&lt;view-page name=&quot;sampleModHome&quot; /&gt;
		&lt;/event-handler&gt;
		
		&lt;event-handler event=&quot;sampleProtectedEvent&quot; access=&quot;public&quot;&gt;
                        &lt;filter name=&quot;adminsOnlyFilter&quot; /&gt;
			&lt;view-page name=&quot;sampleProtectedView&quot; /&gt;
		&lt;/event-handler&gt;
	&lt;/event-handlers&gt;
	
	&lt;!-- SUBROUTINES --&gt;
	
	&lt;!-- PAGE-VIEWS --&gt;
	&lt;page-views&gt;
		&lt;!-- View Loaders --&gt;
		&lt;!-- This loads all pages which match /views/**/*.cfm, so a page-view called aboutUs.index would translate to /views/aboutUs/index.cfm --&gt;
		&lt;view-loader type=&quot;MachII.framework.viewLoaders.PatternViewLoader&quot; /&gt;
		&lt;!-- Define all other page-views here --&gt;
	&lt;/page-views&gt;
	
	&lt;!-- PLUGINS --&gt;
	
&lt;/mach-ii&gt;
&lt;/code&gt;

&lt;strong&gt;&amp;lt;includes&amp;gt;&lt;/strong&gt;

You can include other configuration XML files in your module XML configuration file with no problem. In this example, I&apos;ve included a Mach-II property for ColdSpring because there are certain objects that I want managed by ColdSpring and that are only pertinent to this module. I&apos;ll talk more about Mach-II modules and ColdSpring in an upcoming post, but I did want to show you how you&apos;d configure the module to utilize ColdSpring, should you need to (and you most likely will).

&lt;strong&gt;&amp;lt;properties&amp;gt;&lt;/strong&gt;

At a minmum, you need to include two properties in your module&apos;s Mach-II config file:

&lt;ol&gt;
&lt;li&gt;applicationRoot &amp;mdash; The absolute path to your module under Webroot&lt;/li&gt;
&lt;li&gt;defaultEvent &amp;mdash; The default event to call should no event be specified by a request&lt;/li&gt;
&lt;/ol&gt;

Notice that the following Mach-II properties you would have in a Mach-II XML configuration are &lt;em&gt;not&lt;/em&gt; listed here:

&lt;ul&gt;
&lt;li&gt;eventParameter&lt;/li&gt;
&lt;li&gt;parameterPrecedence&lt;/li&gt;
&lt;li&gt;maxEvents&lt;/li&gt;
&lt;li&gt;MACHII_CONFIG_MODE&lt;/li&gt;
&lt;li&gt;urlBase or any of the URL rewriting properties&lt;/li&gt;
&lt;/ul&gt;

All of these properties have to be defined at the main application level and cannot be overridden at the module level.

You can include the following properties in your module&apos;s Mach-II XML config to override what&apos;s being used in the main application:

&lt;ul&gt;
&lt;li&gt;exceptionEvent&lt;/li&gt;
&lt;li&gt;Module-specific caching property&lt;/li&gt;
&lt;li&gt;Module-specific logging property&lt;/li&gt;
&lt;/ul&gt;

While you &lt;em&gt;can&lt;/em&gt; include these here, I would recommend that you handle exceptions, caching and logging at the main application level. This way you consolidate your exception handling, caching and logging setup in to a single location and don&apos;t wonder why you&apos;ve set up logging in the main application but it&apos;s not logging as expected in the module due to a configuration override there. There are perfectly legitimate reasons to handle exceptions at the individual module level. I just prefer to do it centrally.

&lt;strong&gt;&amp;lt;listeners&amp;gt;&lt;/strong&gt;

You define listeners here exactly as you would in a main Mach-II XML configuration file. Nothing special here. Move on. 

&lt;strong&gt;&amp;lt;filters&amp;gt;&lt;/strong&gt;

Any filters that are needed for this module and this module only are defined here. You&apos;ll notice in my configuration file that I call a filter in the sampleProtectedEvent event, but I don&apos;t define any such filter in this XML config file. How can this possibly work?

Your module inherits all of the properties, event filters, and plugins defined in your parent (main) Mach-II configuration file. So if you have a &quot;admins only&quot; filter which you use to only let administrators access certain events in your application, define it in your parent (main) Mach-II configuration file. You can then refer to that filter in any of the module Mach-II configuration files that operate under the parent app. This is much cleaner, simpler, and more encapsulated than defining a &quot;admins only&quot; filter in each of your modules. You&apos;re free to write a special &quot;admins only&quot; filter for a specific module that has special requirements, of course, and you&apos;d define it in this block if that is what you need to do.

&lt;strong&gt;&amp;lt;event-handlers&amp;gt;&lt;/strong&gt;

Event handlers are defined exactly as they are in the main Mach-II XML configuration file. Nothing special here. Move on. 

&lt;strong&gt;&amp;lt;page-views&amp;gt;&lt;/strong&gt;

As with listeners and event-handlers, page views are defined exactly as they are in the main Mach-II XML configuration file. The &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/MachII1.8SpecificationViewLoaders&quot;&gt;&amp;lt;view-loader&amp;gt; introduced in Mach-II 1.8&lt;/a&gt; is a godsend and helps to remove all of the endless page-view declarations you&apos;d normally find in a Mach-II XML configuration file, and if you&apos;re not using it, you should.

&lt;strong&gt;&amp;lt;plugins&amp;gt;&lt;/strong&gt;

As previously mentioned, your module inherits all of the properties, event filters, and plugins defined in your parent (main) Mach-II configuration file. As such, you&apos;d find common plugins like &quot;is the user logged in plugin&quot; and &quot;put properties from a property CFC in to the current event plugin&quot; defined at the main application level. Every event in your module would be subject to the plugins in your main application running on each and every event in the module, just as they do in the main application.

If you have a plugin which needs to run on every event in your module, define it here and it will work as expected.

There is one additional configuration option you can provide for plugins in a module, and that&apos;s the runParent attribute. This attribute tells Mach-II when your module plugins should be run in relation to the plugins in the parent/main app. As I mentioned in my first post in this series, I haven&apos;t used this myself because I keep to the default behavior in this regard. I&apos;ll simply quote from the &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/ConfigFileExplained&quot;&gt;Mach-II docs&lt;/a&gt; and you can take it from there:

&lt;blockquote&gt;
Defines if or when parent (base application) plugins should be run. This attribute only applies to Mach-II module XML configuration files and has no effect if defined in a base application. A value of after will run the defined module plugins first then the parent plugins, a value of before will run the parent plugins first then the module plugins and a value of none will run only the module plugins with no parent plugins whatsoever. The default value is after if not defined and the XML configuration file is a module.
&lt;/blockquote &gt;

&lt;strong&gt;Including Your Module&apos;s Config File in the Main App Config File&lt;/strong&gt;

The developers behind Mach-II made it super easy to add a module to any existing Mach-II application. To add a module to an existing Mach-II application, you simply need a &amp;lt;modules&amp;gt; block which tells Mach-II where to find each module you want to include.

&lt;code&gt;
...all the rest of your main Mach-II config file, including plugins, listeners, events, etc...
&lt;!-- MODULES --&gt;
&lt;modules&gt;
     &lt;module name=&quot;sampleMod&quot; file=&quot;/myApp/modules/sampleMod/sampleModConfigFile.xml&quot; /&gt;
&lt;/modules&gt;
&lt;/code&gt;

That&apos;s it. It takes nothing more than a single line of XML to include your super-complex module in your main application.

If you want to pass startup parameters to your module, you can do that too. Here&apos;s the example from the Mach-II Dashboard module:

&lt;code&gt;
&lt;module name=&quot;dashboard&quot; file=&quot;/MachIIDashboard/config/mach-ii_dashboard.xml&quot;&gt;
     &lt;mach-ii&gt;
           &lt;properties&gt;
                &lt;property name=&quot;password&quot; value=&quot;superSecretPassword&quot; /&gt;
           &lt;/properties&gt;
     &lt;/mach-ii&gt;
&lt;/module&gt;
&lt;/code&gt;

The name that you give the module here (in the name=&quot;&quot; attribute) is really important. The name gets prepended (that is, put before) every event name generated by Mach-II functions such as BuildURL(), BuildURLToModule(), and the &amp;lt;view:a&amp;gt; tag. You also have to include that module name in any links you hand-build to the other events in your module, or other modules in the larger application. It&apos;s what tells the framework to look for an event within a specific module, and not in the main Mach-II app itself. So an event name like &quot;dashboard:main&quot; would look for an event called &quot;main&quot; inside of the &quot;dashboard&quot; module. To use the sample module XML config file above, an event with the name &quot;sampleMod:sampleProtectedEvent&quot; would look for the event &quot;sampleProtectedEvent&quot; inside the module named &quot;sampleMod.&quot;

If you fail to prepend the module name (or identifier) to the event name, Mach-II looks for an event with the given event name in the the main application. You&apos;ll most likely end up with a &quot;missingEvent&quot; exception as a result.

I&apos;m going to cover modules and Mach-II views in more detail in an upcoming post. In the meantime, if you have any questions, comments, or corrections (I&apos;m looking at you, Peter!), please post away! 
				</description>
				
				<category>Mach-II</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Mon, 16 Nov 2009 08:55:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2009/11/16/MachII-and-Module-Config-Files</guid>
				
			</item>
			
			<item>
				<title>A Brief Series on Mach-II Modules</title>
				<link>http://www.iterateme.com/blog/index.cfm/2009/11/10/A-Brief-Series-on-MachII-Modules</link>
				<description>
				
				I&apos;ve been doing a &lt;em&gt;lot&lt;/em&gt; of work with modules in &lt;a href=&quot;http://www.mach-ii.com/&quot;&gt;Mach-II&lt;/a&gt; in the past couple months and thought I&apos;d blog about some of the stumbling blocks I&apos;ve encountered.

First, a little background:

A Mach-II module is an application which runs inside of a parent Mach-II application. A module usually groups together common functionality in to a related package, encapsulates that package nicely within your Mach-II app, and inherits a lot of the base configuration from the parent Mach-II application. Some people build Mach-II modules that are meant to be reused across multiple applications, for multiple sites, while others build open-source modules which are meant to be redistributable and used by anyone, anywhere. My situation is a little different.

I&apos;m in the process of re-architecting one of our major applications, getting years of old cruff and rebuilding everything on top of Mach-II 1.8. A large part of this project entails taking some existing Mach-II apps (build under 1.1, 1.5 and 1.6) and integrating them in to the new, main Mach-II 1.8 app. A good amount of the work involves throwing out what&apos;s handled by the parent app, adding in new parent-child integration points where needed, and refactoring views to get them to work inside of modules.

So that&apos;s the context for my work. Your experience may be different, of course, especially if you are looking to build a standalone module that can be integrated in to anyone&apos;s Mach-II app, like the super-fantastic Mach-II Dashboard application or Mach Blog. (BTW: If you develop with Mach-II and you&apos;re not using the Mach-II Dashboard application, you&apos;re wasting time and effort. Single-listener, plugin, filter or config reload is a &lt;em&gt;huge&lt;/em&gt; timesaver &amp;mdash; and that&apos;s only part of what you can do with the Dashboard.)

The &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/IncludesAndModules&quot;&gt;full introduction to Mach-II modules&lt;/a&gt; can be found on the Mach-II wiki. I&apos;m going to assume that you&apos;re quite familiar with how Mach-II works and know your way around a Mach-II configuration file.

I also want to say that I&apos;ve not used each and every feature supported by Mach-II modules. I&apos;ve not had need (yet) for things like the runParent attribute of the &amp;lt;plugin&amp;gt; tag. If you&apos;re interested in that topic, please see &lt;a href=&quot;http://groups.google.com/group/mach-ii-for-coldfusion/browse_thread/thread/fe36fb241e5a1609/f7e5a32ad9a93fa4?lnk=gst&amp;q=runparent#f7e5a32ad9a93fa4&quot;&gt;this thread on the always-useful Mach-II Google group&lt;/a&gt;.

There&apos;s a lot of ground to cover, so I thought I&apos;d break things apart in to a series of posts:

&lt;ul&gt;
&lt;li&gt;Modules and Mach-II config files&lt;/li&gt;
&lt;li&gt;Modules and ColdSpring&lt;/li&gt;
&lt;li&gt;Modules and Views&lt;/li&gt;
&lt;li&gt;Converting an Existing App to a Module&lt;/li&gt;
&lt;/ul&gt;

I&apos;m going to &lt;em&gt;try&lt;/em&gt; to get one of these out a week. In the end, if Team Mach-II finds it interesting, useful, and remotely accurate, I&apos;ll consolidate some of this to post on the Mach-II &lt;a href=&quot;http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki&quot;&gt;wiki&lt;/a&gt;. 
				</description>
				
				<category>Mach-II</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Tue, 10 Nov 2009 10:40:00-0400</pubDate>
				<guid>http://www.iterateme.com/blog/index.cfm/2009/11/10/A-Brief-Series-on-MachII-Modules</guid>
				
			</item>
			</channel></rss>