<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>RSS feed for InstantSpot site Blog of Dave</title><link>http://daveshuck.instantspot.com</link><description>Dave Shuck&apos;s ramblings on - ColdFusion, Flex, and Java, and life.</description><language>en-us</language><copyright>This work is Copyright &#xA9; 2010 by Blog of Dave</copyright><generator>RSSVille ColdFusion FeedMaker, version 1.0</generator><pubDate>Sun, 14 Mar 2010 07:48:15 GMT</pubDate><item><title>ColdFusion 9 bug: Change in behavior with CGI variables</title><link>http://daveshuck.instantspot.com/blog/2010/03/12/ColdFusion-9-bug-Change-in-behavior-with-CGI-variables/</link><description>&lt;p&gt;&lt;strong&gt;EDIT:&amp;nbsp; &lt;/strong&gt;&lt;em&gt;As Raymond Camden has pointed out in the comments, this is actually documented behavior, so&amp;nbsp;I would like to state that this obviously isn&apos;t a bug in ColdFusion.&amp;nbsp; However the fact remains that two developers (the only 2 out of 12+ that have upgraded to CF9) are seeing different behavior after upgrading to CF9 than the rest of the team. &amp;nbsp;Unfortunately I will be unable to test this further until 3/15 and will update this post then.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Our company has an application that leverages SiteMinder for authentication.&amp;nbsp; One of our developers, Andrew Leaf, noticed that when he installed ColdFusion 9 that he could no longer authenticate to the application.&amp;nbsp; I was using an early beta version of CF9 and had no problems, so I initially dismissed the notion that this could be a ColdFusion 9 issue.&amp;nbsp; After spending some time with Andrew as he walked through the ColdFusion Builder step debugger, we found the suspect block of code.&amp;nbsp; The application code checked to see if a CGI variable has been set using StructKeyExists() and if it does, it sets session information based on that value.&amp;nbsp; Today I set ColdFusion 9 up on new machine and am seeing the exact same behavior.&amp;nbsp; What we are seeing is that with ColdFusion 9, when you test for existence of *any* variables in the CGI scope, it always returns true.&lt;br /&gt; &lt;br /&gt; It essentially behaves in such a way that any variable name appears to be defined and paramed with a blank value in the CGI scope.&amp;nbsp; For instance:&lt;br /&gt; &lt;b&gt;&amp;lt;cfdump var=&amp;quot;#StructKeyExists(cgi,&amp;quot;someRandomString&amp;quot;)&amp;quot; /&amp;gt;&lt;/b&gt; outputs YES&lt;br /&gt; &lt;br /&gt; Likewise:&lt;br /&gt; &lt;b&gt;&amp;lt;cfdump var=&amp;quot;#cgi.someRandomString#&amp;quot; /&amp;gt;&lt;/b&gt; outputs [empty string]&lt;/p&gt;</description><pubDate>Fri, 12 Mar 2010 20:52:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2010/03/12/ColdFusion-9-bug-Change-in-behavior-with-CGI-variables/</guid><category>ColdFusion,Technology,CFML</category></item><item><title>Need a &quot;rock star&quot; ColdFusion speaker for 7/30/2010 event in Dallas</title><link>http://daveshuck.instantspot.com/blog/2010/03/03/Need-a-rock-star-ColdFusion-speaker-for-7302010-event-in-Dallas/</link><description>Last year was the second annual &lt;a href=&quot;http://www.dallastechfest.com&quot;&gt;Dallas TechFest&lt;/a&gt;, which is a 1-day multi-platform event centered around programming.&amp;nbsp; They approached me at that time about bringing ColdFusion into the event, and giving us a dedicated track in one of the rooms.&amp;nbsp; I made a optimistic claim that we could bring in 50+ CFML devs from the area, and low and behold, we ended up with 70+ people that registered with the discount code from &lt;a href=&quot;http://www.dfwcfug.org&quot;&gt;our user group&lt;/a&gt;.&amp;nbsp; It was very successful and had a good buzz with the local community.&amp;nbsp; Additionally, we blew the PHP and Ruby groups out of the water! :)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;For 2010, the organizers have offered a travel and expenses budget to to each track (CF being one of those) to pay for travel and expenses to get one &quot;rock star&quot; from each of the technologies. Based on last year&apos;s attendees, I would say that a large percentage were beginner-intermediate, with our regular core of advanced guys around as well.&amp;nbsp; The event will be on Friday July 30, in Addison.&amp;nbsp; Unfortunately this falls during the same week as &lt;a href=&quot;http://cfunited.com/2010/&quot;&gt;CFUnited&lt;/a&gt;, which obviously zaps a number of speakers from the pool of availability, but if you are interested in speaking, please let me know!&amp;nbsp; I am dshuck pretty much everywhere... gmail, twitter, facebook, etc.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=a89de899-3fe6-8c45-8d90-066016cfdc53&quot; /&gt;&lt;/div&gt;</description><pubDate>Wed, 03 Mar 2010 17:24:55 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2010/03/03/Need-a-rock-star-ColdFusion-speaker-for-7302010-event-in-Dallas/</guid><category>ColdFusion,General,Technology,Conferences,CFML</category></item><item><title>UDF: pcase() - Captilize first letter of each word in a string</title><link>http://daveshuck.instantspot.com/blog/2010/02/25/UDF-pcase--Captilize-first-letter-of-each-word-in-a-string/</link><description>This is a UDF that I keep on hand for converting strings to &quot;proper case&quot;, such as a person&apos;s name.&amp;nbsp; For instance, in a database we might have a name stored like &lt;b&gt;DAVID B. SHUCK&lt;/b&gt;, but when they log into our site and we welcome them, we don&apos;t necessarily want to shout it at them!&amp;nbsp;&amp;nbsp; Saying &quot;Hello David B. Shuck...&quot; would hopefully be a bit less abrasive.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Enter the user-defined function pcase().&amp;nbsp; Through the use of regular expressions we are doing a search for word patterns and capitalizing the first letter in each word.&amp;nbsp; Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;cffunction name=&quot;pcase&quot; access=&quot;public&quot; output=&quot;false&quot;  returntype=&quot;string&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;cfargument name=&quot;string&quot;  type=&quot;string&quot; required=&quot;true&quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;cfreturn  REReplaceNoCase(LCase(arguments.string),&quot;(^[a-z*]|[ *][a-z*])&quot;,&quot;\U\1\E&quot;,&quot;all&quot;)  /&amp;gt;&lt;br /&gt;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;/code&gt;</description><pubDate>Thu, 25 Feb 2010 16:34:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2010/02/25/UDF-pcase--Captilize-first-letter-of-each-word-in-a-string/</guid><category>ColdFusion,Tips and Tricks,Technology,CFML,UDF</category></item><item><title>Implicit constructor and CF9 style implicit accessors without ColdFusion 9</title><link>http://daveshuck.instantspot.com/blog/2010/02/25/Implicit-constructor-and-CF9-style-implicit-accessors-without-ColdFusion-9/</link><description>One of the broadly welcomed features of ColdFusion 9 has been the addition of implicit getters and setters to CFCs.&amp;nbsp; What this means is that you no longer have to hand code the repetitive boiler plate getXXX() and setXXX() methods for each property in your model objects. However, you don&apos;t need ColdFusion 9, (or even ColdFusion for that matter) to enjoy the benefits of the new implicit accessors with the version 9 release.&amp;nbsp; Since ColdFusion 8, developers have had access to the OnMissingMethod() method which makes tasks like this very simple to implement on your own.&amp;nbsp; The OnMissingMethod is also available in current versions of OpenBlueDragon and Railo.&lt;br /&gt;&lt;br /&gt;For my implementation of this, I use a standard BaseBean class in a number of my projects which is extended by all of my model class objects.&amp;nbsp; By leveraging the OnMissingMethod() in this BaseBean, I create these implicit accessors, in addition to an implicit constructor &lt;b&gt;init()&lt;/b&gt; method as well.&lt;br /&gt;&lt;br /&gt;There are multiple examples on the internet that show how you can use OnMissingMethod(), but for the most part, the examples that I have come across do not protect the class from being having infinite previously undefined properties added to it from the outside.&amp;nbsp; For instance, I could have a class named Person.cfc with define properties of &quot;firstName&quot; and &quot;lastName&quot;, but nothing would stop someone from doing &lt;b&gt;Person.setThisIsNotAProperty(true)&lt;/b&gt; and that value would be dynamically added to the Person instance.&lt;b&gt;&amp;nbsp; &lt;/b&gt;While some might argue that the flexibility that this approach offers is a positive thing, I prefer to lock my classes down just a bit more.&amp;nbsp; For instance&lt;b&gt; &lt;/b&gt;I like the fact that I can open up a model class and see exactly what properties it can contain with clearly defined &amp;lt;cfproperty/&amp;gt; tags.&amp;nbsp;&amp;nbsp; From a maintainability standpoint the idea of &quot;mystery&quot; dynamic properties strike me as just wrong.&lt;br /&gt;&lt;br /&gt;For my implicit constructor, I take an approach where I loop through any named arguments that were passed, and if the name matches a property that I have defined with &amp;lt;cfproperty/&amp;gt;, then it will be passed to a setter method.&amp;nbsp; Any arguments that are passed that are not defined as a property are discarded.&lt;br /&gt;&lt;br /&gt;So let&apos;s take a look at what this looks like.&amp;nbsp; First I will paste the entire BaseBean, and below we will break it apart to discuss what is going on.&lt;br /&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfcomponent output=&amp;quot;false&amp;quot;&amp;gt;       &amp;lt;cffunction name=&amp;quot;init&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;BaseBean&amp;quot;&amp;gt;   &amp;lt;cfset var i = &amp;quot;&amp;quot; /&amp;gt;   &amp;lt;cfset initializePropertyList() /&amp;gt;   &amp;lt;cfloop list=&amp;quot;#this.propertyList#&amp;quot; index=&amp;quot;i&amp;quot;&amp;gt;    &amp;lt;cfif StructKeyExists(arguments,i)&amp;gt;     &amp;lt;cfset set(i,arguments[i]) /&amp;gt;    &amp;lt;/cfif&amp;gt;   &amp;lt;/cfloop&amp;gt;     &amp;lt;cfreturn this /&amp;gt;  &amp;lt;/cffunction&amp;gt;      &amp;lt;cffunction name=&amp;quot;initializePropertyList&amp;quot; access=&amp;quot;private&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;void&amp;quot;&amp;gt;   &amp;lt;cfset var i = &amp;quot;&amp;quot; /&amp;gt;   &amp;lt;cfif NOT StructKeyExists(this,&amp;quot;propertyList&amp;quot;)&amp;gt;    &amp;lt;cfset this.propertyList = &amp;quot;&amp;quot; /&amp;gt;    &amp;lt;cfif ArrayLen(GetMetadata(this).properties)&amp;gt;     &amp;lt;cfloop from=&amp;quot;1&amp;quot; to=&amp;quot;#ArrayLen(GetMetadata(this).properties)#&amp;quot; index=&amp;quot;i&amp;quot;&amp;gt;      &amp;lt;cfset this.propertyList = ListAppend(this.propertyList,GetMetadata(this).properties[i].name)&amp;gt;     &amp;lt;/cfloop&amp;gt;    &amp;lt;/cfif&amp;gt;   &amp;lt;/cfif&amp;gt;     &amp;lt;cfreturn /&amp;gt;   &amp;lt;/cffunction&amp;gt;      &amp;lt;cffunction name=&amp;quot;onMissingMethod&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;any&amp;quot;&amp;gt;   &amp;lt;cfargument name=&amp;quot;missingMethodName&amp;quot; type=&amp;quot;string&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;   &amp;lt;cfargument name=&amp;quot;missingMethodArguments&amp;quot; type=&amp;quot;struct&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;      &amp;lt;cfset var property = &amp;quot;&amp;quot; /&amp;gt;            &amp;lt;cfif ReFindNoCase(&amp;quot;^[gs](et)&amp;quot;,arguments.missingMethodName)&amp;gt;    &amp;lt;cfset property = ReReplaceNoCase(arguments.missingMethodName,&amp;quot;^[gs](et)&amp;quot;,&amp;quot;&amp;quot;) /&amp;gt;    &amp;lt;cfset initializePropertyList() /&amp;gt;     &amp;lt;cfif ListFindNoCase(this.propertyList,property)&amp;gt;     &amp;lt;cfif StructIsEmpty(arguments.missingMethodArguments)&amp;gt;      &amp;lt;cfreturn get(property) /&amp;gt;     &amp;lt;cfelse&amp;gt;      &amp;lt;cfset set(property,arguments.missingMethodArguments[1]) /&amp;gt;      &amp;lt;cfreturn this /&amp;gt;     &amp;lt;/cfif&amp;gt;     &amp;lt;cfelse&amp;gt;     &amp;lt;cfthrow message=&amp;quot;The class #GetMetadata(this).name# does not have a property named #property# so the implicit #arguments.missingMethodName#() method is not available.&amp;quot; /&amp;gt;      &amp;lt;/cfif&amp;gt;    &amp;lt;/cfif&amp;gt;    &amp;lt;cfreturn /&amp;gt;   &amp;lt;/cffunction&amp;gt;    &amp;lt;cffunction name=&amp;quot;get&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;any&amp;quot;&amp;gt;   &amp;lt;cfargument name=&amp;quot;property&amp;quot; type=&amp;quot;string&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;   &amp;lt;cfset var value = &amp;quot;&amp;quot; /&amp;gt;        &amp;lt;cfset value = variables[arguments.property] /&amp;gt;       &amp;lt;cfreturn value /&amp;gt;   &amp;lt;/cffunction&amp;gt;    &amp;lt;cffunction name=&amp;quot;set&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;void&amp;quot;&amp;gt;   &amp;lt;cfargument name=&amp;quot;property&amp;quot; type=&amp;quot;string&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;   &amp;lt;cfargument name=&amp;quot;value&amp;quot; type=&amp;quot;any&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;      &amp;lt;cfset variables[arguments.property] = arguments.value /&amp;gt;      &amp;lt;cfreturn /&amp;gt;  &amp;lt;/cffunction&amp;gt;   &amp;lt;/cfcomponent&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Before we walk through the actual flow, I would like to point out the method &lt;b&gt;initializePropertyList()&lt;/b&gt; that you see here:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cffunction name=&amp;quot;initializePropertyList&amp;quot; access=&amp;quot;private&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;void&amp;quot;&amp;gt;  &amp;lt;cfset var i = &amp;quot;&amp;quot; /&amp;gt;  &amp;lt;cfif NOT StructKeyExists(this,&amp;quot;propertyList&amp;quot;)&amp;gt;   &amp;lt;cfset this.propertyList = &amp;quot;&amp;quot; /&amp;gt;   &amp;lt;cfif ArrayLen(GetMetadata(this).properties)&amp;gt;    &amp;lt;cfloop from=&amp;quot;1&amp;quot; to=&amp;quot;#ArrayLen(GetMetadata(this).properties)#&amp;quot; index=&amp;quot;i&amp;quot;&amp;gt;     &amp;lt;cfset this.propertyList = ListAppend(this.propertyList,GetMetadata(this).properties[i].name)&amp;gt;    &amp;lt;/cfloop&amp;gt;   &amp;lt;/cfif&amp;gt;  &amp;lt;/cfif&amp;gt;    &amp;lt;cfreturn /&amp;gt;  &amp;lt;/cffunction&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;By using the GetMetadata() function, we are able to introspect our instance and create a list of property names which we can reference in our other methods.&amp;nbsp; This is what enables us to enforce the rules that I described above in which we make sure that a property exists before setting it in the constructor or through an implicit accessor.&amp;nbsp; You will see in both the &lt;b&gt;init() &lt;/b&gt;and &lt;b&gt;OnMissingMethod()&lt;/b&gt; methods that we call this method to ensure the list of properties is available before testing against it.&lt;br /&gt;&lt;br /&gt;With that established, let&apos;s take a look at the &lt;b&gt;init()&lt;/b&gt; constructor method:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cffunction name=&amp;quot;init&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;BaseBean&amp;quot;&amp;gt;  &amp;lt;cfset var i = &amp;quot;&amp;quot; /&amp;gt;  &amp;lt;cfset initializePropertyList() /&amp;gt;  &amp;lt;cfloop list=&amp;quot;#this.propertyList#&amp;quot; index=&amp;quot;i&amp;quot;&amp;gt;   &amp;lt;cfif StructKeyExists(arguments,i)&amp;gt;    &amp;lt;cfset set(i,arguments[i]) /&amp;gt;   &amp;lt;/cfif&amp;gt;  &amp;lt;/cfloop&amp;gt;    &amp;lt;cfreturn this /&amp;gt; &amp;lt;/cffunction&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;After making sure that our propertyList has been initialized, we loop through that list and if there is a matching named argument, we call the &lt;b&gt;set()&lt;/b&gt; method which sets that value into the variables scope.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;br /&gt;So with the object initialized, let&apos;s take a look at our accessors.&amp;nbsp; For our example, let&apos;s say that we have a &lt;b&gt;Person&lt;/b&gt; object and we are doing to set our &lt;b&gt;firstName&lt;/b&gt; property like this: &lt;b&gt;person.setFirstName(&quot;Dave&quot;)&lt;/b&gt;.&amp;nbsp; Since that setter method doesn&apos;t exist in our Person class, the OnMissingMethod() below will be invoked.&amp;nbsp; &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cffunction name=&amp;quot;onMissingMethod&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;any&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;missingMethodName&amp;quot; type=&amp;quot;string&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;  &amp;lt;cfargument name=&amp;quot;missingMethodArguments&amp;quot; type=&amp;quot;struct&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;    &amp;lt;cfset var property = &amp;quot;&amp;quot; /&amp;gt;          &amp;lt;cfif ReFindNoCase(&amp;quot;^[gs](et)&amp;quot;,arguments.missingMethodName)&amp;gt;   &amp;lt;cfset property = ReReplaceNoCase(arguments.missingMethodName,&amp;quot;^[gs](et)&amp;quot;,&amp;quot;&amp;quot;) /&amp;gt;   &amp;lt;cfset initializePropertyList() /&amp;gt;    &amp;lt;cfif ListFindNoCase(this.propertyList,property)&amp;gt;    &amp;lt;cfif StructIsEmpty(arguments.missingMethodArguments)&amp;gt;     &amp;lt;cfreturn get(property) /&amp;gt;    &amp;lt;cfelse&amp;gt;     &amp;lt;cfset set(property,arguments.missingMethodArguments[1]) /&amp;gt;     &amp;lt;cfreturn this /&amp;gt;    &amp;lt;/cfif&amp;gt;    &amp;lt;cfelse&amp;gt;    &amp;lt;cfthrow message=&amp;quot;The class #GetMetadata(this).name# does not have a property named #property# so the implicit #arguments.missingMethodName#() method is not available.&amp;quot; /&amp;gt;     &amp;lt;/cfif&amp;gt;   &amp;lt;/cfif&amp;gt;   &amp;lt;cfreturn /&amp;gt;  &amp;lt;/cffunction&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;We are then doing a regular expression test to see if the missing method names starts with either &quot;get&quot; or &quot;set&quot;.&amp;nbsp; If so, we derive the name of the target property by stripping the &quot;get&quot; or &quot;set&quot; off of the string.&amp;nbsp; After making sure that our propertyList has been defined, we then look in that list to see if the target property actually exists in the instance.&amp;nbsp; If it does, the request is then routed on to either the getter or the setter depending on whether arguments were passed to it.&amp;nbsp; Otherwise an exception will be thrown to let the developer know that he or she has attempted to access an undefined property.&lt;br /&gt;&lt;br /&gt;One thing you might notice is that when our conditional block routes the request to the setter, we return an instance of the class itself.&amp;nbsp; This allows us to do method chaining like this:&amp;nbsp; &lt;b&gt;person.setFirstName(&quot;Dave&quot;).setLastName(&quot;Shuck&quot;)&lt;/b&gt;.&amp;nbsp; it should be noted that this is not the approach that Adobe took with ColdFusion 9.&lt;br /&gt;&lt;br /&gt;So let&apos;s take a look at it in action.&amp;nbsp; Here is our Person.cfc class.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfcomponent output=&amp;quot;false&amp;quot; extends=&amp;quot;BaseBean&amp;quot;&amp;gt;    &amp;lt;cfproperty name=&amp;quot;id&amp;quot; type=&amp;quot;string&amp;quot; /&amp;gt;  &amp;lt;cfproperty name=&amp;quot;firstName&amp;quot; type=&amp;quot;string&amp;quot; /&amp;gt;  &amp;lt;cfproperty name=&amp;quot;lastName&amp;quot; type=&amp;quot;string&amp;quot; /&amp;gt;   &amp;lt;/cfcomponent&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;As you can see in the &amp;lt;cfcomponent/&amp;gt; tag, we are extending our BaseBean which is all that we need to have a workable domain class object. &lt;br /&gt;&lt;br /&gt;When we put this together and access it in our code, we can do this:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfset person = CreateObject(&amp;quot;component&amp;quot;,&amp;quot;Person&amp;quot;).init(id=7,firstName=&amp;quot;Dave&amp;quot;, lastName=&amp;quot;Shuck&amp;quot;) /&amp;gt;  &amp;lt;cfdump var=&amp;quot;#person#&amp;quot; /&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/100225/implicit-accessors/person_dump_1.png&quot; /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;br /&gt;Once we have an instance, we can modify those properties like so:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfset person.setId(8).setFirstName(&amp;quot;Johnny&amp;quot;).setLastName(&amp;quot;Rotten&amp;quot;) /&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/100225/implicit-accessors/person_dump_2.png&quot; /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;br /&gt;I have not actually tested this on Railo, but I can confirm that it works in OpenBlueDragon (including GAE version), and ColdFusion versions 8 and 9.&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=2c92c98f-15c9-815f-9118-37ac4f41aacc&quot; /&gt;&lt;/div&gt;</description><pubDate>Thu, 25 Feb 2010 11:56:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2010/02/25/Implicit-constructor-and-CF9-style-implicit-accessors-without-ColdFusion-9/</guid><category>ColdFusion,Tips and Tricks,Technology,CFML</category></item><item><title>Link to the HFDP 4 CF Connect recordings</title><link>http://daveshuck.instantspot.com/blog/2010/02/09/Link-to-the-HFDP-4-CF-Connect-recordings/</link><description>I have been asked more times than I would like to admit to put together a list of the meeting recordings that we have archived for our &quot;Head First Design Patterns for ColdFusion Developers&quot; series that the &lt;a href=&quot;http://dfwcfug.instantspot.com&quot;&gt;DFWCFUG&lt;/a&gt; has been doing since September of last year.&amp;nbsp; I will be appending to that entry in the next couple of months as we near the end, so you may want to bookmark it for future reference if you are interested in following.&lt;br /&gt;&lt;br /&gt;The entire archive &lt;a href=&quot;http://www.dfwcfug.org/blog/2010/02/09/Recording-list-for-Head-First-Design-Patterns-for-CFML-presentations&quot;&gt;can be found here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=3c151189-0ee2-8354-b84e-67e00f57cc10&quot; /&gt;&lt;/div&gt;</description><pubDate>Wed, 10 Feb 2010 03:00:15 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2010/02/09/Link-to-the-HFDP-4-CF-Connect-recordings/</guid><category>ColdFusion,Technology</category></item><item><title>Naked Domains in Google App Engine with GoDaddy</title><link>http://daveshuck.instantspot.com/blog/2009/12/16/Naked-Domains-in-Google-App-Engine-with-GoDaddy/</link><description>I recently set up a new site (&lt;a href=&quot;http://www.hikethecanyon.org&quot;&gt;hikethecanyon.org&lt;/a&gt;) on the &lt;a href=&quot;http://appengine.google.com/&quot;&gt;Google App Engine&lt;/a&gt; running &lt;a href=&quot;http://www.openbluedragon.org&quot;&gt;OpenBlueDragon&lt;/a&gt;.&amp;nbsp; By default when you set up a new site on GAE (Google App Engine), you choose an ID for your application, which must be unique on their system as it also serves as the hostname of the URL like this: http://[your ID].appspot.com.&amp;nbsp;&amp;nbsp; For those that would like to use a different domain name, Google App Engine has mechanisms for doing so.&amp;nbsp; In the administration panel of your application, you can add a domain and then choose hostnames from that domain that the application should respond to.&amp;nbsp; However, it makes no provisions for serving the &quot;naked domain&quot;.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;What does this mean?&amp;nbsp; For my example of hikethecanyon.org, I originally set the site up with an id of &lt;b&gt;hikethecanyon-org &lt;/b&gt;which was initially served as &lt;b&gt;http://hikethecanyon-org.appspot.com&lt;/b&gt;.&amp;nbsp; After adding the domain hikethecanyon.org, I was able to add the host &quot;www&quot; so that it would respond to &lt;b&gt;http://www.hikethecanyon.org&lt;/b&gt;.&amp;nbsp; However, since GAE doesn&apos;t support naked domains, I was unable to set it up to respond to &lt;b&gt;http://hikethecanyon.org&lt;/b&gt;.&amp;nbsp; I was able find a workaround using GoDaddy&apos;s domain forwarding functionality.&amp;nbsp; While walking fellow CFML developer &lt;a href=&quot;http://blog.kukiel.net/&quot;&gt;Paul Kukiel&lt;/a&gt; through the process today, he mentioned that someone should blog this, so here it is with screenshots along the way &lt;i&gt;(edit - it appears that he decided to blog it himself as well!)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;For my example, I am going to use a domain I have had sitting around doing nothing for a few years (j4n.org) and walk through the process with some screenshots and explanations along the way.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;First, you need to create your application in the GAE dashboard and deploy your application.&amp;nbsp; Many people have covered this topic in our community including Paul Kukiel and &lt;a href=&quot;http://www.aaronjlynch.com&quot;&gt;Aaron Lynch&lt;/a&gt;, so I will skip to the next step and assume that you have a running application on Google App Engine. As you can see below, I have set up an app with an ID of &lt;b&gt;j4n-org&lt;/b&gt; that is answering on &lt;b&gt;http://j4n-org.appspot.com&lt;/b&gt; which is just running a Mach-II skeleton application.&lt;br /&gt;&lt;div align=&quot;left&quot;&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/mach_ii_skeleton.png&quot; height=&quot;514&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;The next thing that we want to do is add the &lt;b&gt;j4n.org&lt;/b&gt; domain to this application.&amp;nbsp; When you go into the GAE dashboard, you will see that option under the &quot;Application Settings&quot; section labeled &quot;Domain Setup&quot;&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/gae_admin_add_domain_button.png&quot; height=&quot;502&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;On this page you will see a note that tells you that the domain you add must be set up for Google Apps, a service that allows all sorts of functionality, including email services and more.&amp;nbsp; NOTE:&amp;nbsp; You do not have to use any of those services, you simply need to sign up!&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/gae_google_app_required.png&quot; height=&quot;390&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;By clicking the link that says &lt;b&gt;Sign up for Google Apps&lt;/b&gt;, you will be taken to a page like this:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/google_app_enter_domain.png&quot; height=&quot;459&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;Walk through the process filling out your personal information and you will come to a screen that looks like this:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/google_app_create_cname_1.png&quot; height=&quot;455&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For our example, we are going to choose to create a new CNAME record in DNS to prove to Google that we own the domain.&amp;nbsp; By choosing that option&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/google_app_create_cname_2.png&quot; height=&quot;418&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;At this point we need to go to the GoDaddy DNS manager and create a host name &lt;b&gt;google46353a9a2d07a035&lt;/b&gt; and point it to &lt;b&gt;google.com&lt;/b&gt;.&amp;nbsp; You can see what that looks like below:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/godaddy_cname.png&quot; height=&quot;387&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once that record is in place we can go back to the Google Apps page and click the button labeled &lt;b&gt;I&apos;ve completed the steps above&lt;/b&gt;.&amp;nbsp; If all goes well, you will see a page directing you through additional setup.&amp;nbsp; For our purposes in this example, we are done with Google Apps for the time being.&amp;nbsp; Now we want to go back to the GAE dashboard and tell it that we want to use the &lt;b&gt;j4n.org&lt;/b&gt; domain.&lt;br /&gt;&lt;br /&gt;When you enter that domain you should see a message that looks like this:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/gae_admin_add_domain_confirm.png&quot; height=&quot;480&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;This will bring us back into the Google Apps control panel for the &lt;b&gt;j4n.org&lt;/b&gt; domain and we can add hostnames to our application like this:&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/google_app_add_www.png&quot; height=&quot;344&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;When you click add you will see an page like the one below instructing you to add another CNAME to GoDaddy for the host &quot;www&quot;.&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/google_app_add_www_2.png&quot; height=&quot;445&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;In the screen below you will see that we have successfully added the &quot;www&quot; host and while we were in there I went ahead and deleted the temporary CNAME that we had to create earlier to validate the ownership of the domain. &lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/godaddy_add_www.png&quot; height=&quot;482&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At this point we can actually reach our application with the address &lt;b&gt;http://www.j4n.org&lt;/b&gt; as you see below:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/www.j4n.org.png&quot; height=&quot;300&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;While this is pretty cool and all, we still can&apos;t access our application with &lt;b&gt;http://j4n.org&lt;/b&gt;.&amp;nbsp; For this, we will count on GoDaddy to do the rest.&amp;nbsp; Go back into the GoDaddy domain manager look for this link:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/godaddy_forward_manage.png&quot; height=&quot;376&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;On the next page, you will want to fill out the field like you see before.&amp;nbsp; However, before you do, click the &quot;learn more&quot; link in the bottom left corner.&amp;nbsp; On that page there is a very important note:&amp;nbsp; &lt;u&gt;&lt;b&gt;For your domain to forward, your domain&apos;s A record must be &lt;code&gt;64.202.189.170&lt;/code&gt;.&lt;/b&gt;&amp;nbsp;&lt;/u&gt; If you note my DNS information above, that is not what the default parked domain IP is.&amp;nbsp; I won&apos;t bore you with yet another screen shot, but make sure you alter your domain&apos;s A record.&amp;nbsp; Now when we ping &lt;b&gt;j4n.org&lt;/b&gt; we get a response from 64.202.189.170.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Once we enter in &lt;b&gt;www.j4n.org&lt;/b&gt; you can see that our plan is going to work by hitting the &quot;Preview&quot; link to the right and seeing a snapshot of our app!&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://dl.dropbox.com/u/101948/blog/entries/naked_domains_gae/godaddy_forward_add.png&quot; height=&quot;417&quot; width=&quot;600&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You will notice that we accepted the default settings which actually does a 301 redirect from &lt;b&gt;http://j4n.org&lt;/b&gt; to &lt;b&gt;http://www.j4n.org&lt;/b&gt;.&amp;nbsp; This means that we will never actually see &lt;b&gt;http://j4n.org&lt;/b&gt; in the address bar after the page has loaded.&amp;nbsp; If you click on the advanced settings you can select &quot;masking&quot; which allows the url to remain in the address bar as http://j4n.org.&amp;nbsp; Each option has its own advantages.&amp;nbsp; Select what is right for your application and choose OK.&lt;br /&gt;&lt;br /&gt;That is all you need to do!&amp;nbsp; Now, a word of warning... we have all gotten spoiled by the seemingly instant DNS changes in recent years.&amp;nbsp; You will find that when you make this forwarding change, you may need to wait up to half an hour or so before you can see the finished product (your mileage may vary).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=384d57d8-afd1-8848-ba2b-41b2e1f9d6ba&quot; /&gt;&lt;/div&gt;</description><pubDate>Thu, 17 Dec 2009 03:11:47 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/12/16/Naked-Domains-in-Google-App-Engine-with-GoDaddy/</guid><category>ColdFusion,Servers,Technology,Java</category></item><item><title>Relaunched HikeTheCanyon.org on OpenBD and GAE</title><link>http://daveshuck.instantspot.com/blog/2009/12/15/Relaunched-HikeTheCanyonorg-on-OpenBD-and-GAE/</link><description>Around a year or so ago, I inadvertently took &lt;a href=&quot;http://www.hikethecanyon.org&quot;&gt;hikethecanyon.org&lt;/a&gt; offline in a server move.&amp;nbsp; Considering that it is a very low traffic site that is little more than a scrapbook of hiking pictures and descriptions, there is no active user community to send me nasty messages begging for me to bring it back online.&amp;nbsp; Finally this past weekend, I spent a bit of time and revived the code base off an old server, moved all the images out to Amazon S3 and brought the site up running under OpenBlueDragon on the Google App Engine.&amp;nbsp; Other than a very rudimentary Lightbox drop-in I did on the gallery to replace a no-longer functioning Flash image gallery, I didn&apos;t actually touch the codebase or the design.&amp;nbsp; So if it looks dated to you, that is because it is!&amp;nbsp; &lt;br /&gt;&lt;br /&gt;For those interested in hiking, you may want to give it a look.&amp;nbsp; It documents a hike of the Grand Canyon that I took with my dad in 2005 with a very detailed trip report and over 300 pictures.&amp;nbsp; Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.hikethecanyon.org&quot;&gt;&lt;big&gt;&lt;b&gt;HikeTheCanyon.org&lt;/b&gt; - Rim-to-Rim through the Grand Canyon on North Kaibab and the Bright Angel Trail&lt;/big&gt;&lt;/a&gt;&lt;br /&gt;&lt;div align=&quot;center&quot;&gt;&lt;a href=&quot;http://www.hikethecanyon.org&quot;&gt;&lt;img style=&quot;max-width: 800px;&quot; src=&quot;http://daveshuck.instantspot.com/userfiles/073006/91/hikethecanyon.org.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=c80c897b-b851-8081-af34-eee406ccd4f8&quot; /&gt;&lt;/div&gt;</description><pubDate>Tue, 15 Dec 2009 16:44:05 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/12/15/Relaunched-HikeTheCanyonorg-on-OpenBD-and-GAE/</guid><category>ColdFusion,Technology</category></item><item><title>Setting up ColdSpring AOP and interesting behavior with return types</title><link>http://daveshuck.instantspot.com/blog/2009/12/07/Setting-up-ColdSpring-AOP-and-interesting-behavior-with-return-types/</link><description>This weekend I had a task in which I needed to add a behavior onto a method in an existing production method in a service object.&amp;nbsp; The new behavior is more or less notifying a 3rd party application whenever a particular method was being called.&amp;nbsp; Considering that it is not really an essential part of the process, it didn&apos;t really belong inline as part of that method, nor did I really want to affect existing &quot;sealed&quot; production code.&amp;nbsp; Although I understood that the AOP functionality of ColdSpring was designed for exactly that type of work, I had never actually used it before this task.&amp;nbsp; I put together a little proof-of-concept application that validated what I wanted to do, then applied it to my application.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;My goal was to set up an &quot;afterReturningAdvice&quot; object/method - that being a method which will be called at the completion of the target method, which is Member.saveMember() - where I could externalize the new behavior without touching the service itself.&amp;nbsp; While I did get it to perform essentially how I expected, there were a couple of gotchas about this process. One of which makes good sense, the other... not so much.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;For starters, my MemberService was defined in ColdSpring like this...&lt;br /&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;[codeblock 450]&lt;br /&gt;&lt;br /&gt;In order to make this change without causing broad sweeping changes throughout the application (in theory!), we are going to create a proxy object that masquerades as the MemberService that will pass requests onto the original MemberService.&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;[codeblock 451]&lt;br /&gt;&lt;br /&gt;As you can see, our &lt;b&gt;MemberService&lt;/b&gt; is now actually of type &lt;b&gt;coldspring.aop.framework.ProxyFactoryBean&lt;/b&gt;. &amp;nbsp; We have defined its target as a bean named &lt;b&gt;MemberServiceTarget&lt;/b&gt; which points to our original &lt;b&gt;MemberService&lt;/b&gt; that has been renamed.&amp;nbsp; it now has an &quot;interceptors&quot; property that basically wires in a new bean named &lt;b&gt;RecordUpdatedMemberAfterReturningAdvisor&lt;/b&gt; that will serve as an interceptor anytime the &lt;b&gt;&quot;MemberService&quot;&lt;/b&gt; is accessed.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;So lets take a look at our interceptor definition:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;[codeblock 452]&lt;br /&gt;&lt;br /&gt;You can see that the&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;b&gt;RecordUpdatedMemberAfterReturningAdvisor&lt;/b&gt; that we declared in our previous snippet is defined here as type &lt;b&gt;coldspring.aop.support.NamedMethodPointcutAdvisor&lt;/b&gt;, which is a another built-in type in the ColdSpring framework.&amp;nbsp; We have defined a property &quot;mappedNames&quot; which will list any methods in our target object that we would like this interceptor to act on.&amp;nbsp; In our case we are only wanting to act on the &lt;b&gt;saveMember()&lt;/b&gt; method, which you see in the &lt;value&gt; property.&amp;nbsp; The &quot;advice&quot; property tells the interceptor that whenever our &lt;b&gt;saveMember()&lt;/b&gt; method is called, that we need to notify our &lt;b&gt;RecordUpdatedMemberAfterReturningAdvice&lt;/b&gt;. This is an object at we create that extends the &lt;b&gt;coldspring.aop.AfterReturningAdvice &lt;/b&gt;abstract class that is included with the framework.&amp;nbsp; When you use this advice, you must have a concrete implementation of the &lt;b&gt;afterReturning()&lt;/b&gt; method, which is were we will actually put our code that notifies the 3rd party application.&amp;nbsp; That method will contain the arguments: returnVal, method, args, and target, which will let you know all about the target method that was just called.&amp;nbsp; Pretty cool huh?&lt;br /&gt;&lt;br /&gt;Here is what that &lt;/value&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;b&gt;RecordUpdatedMemberAfterReturningAdvice&lt;/b&gt; looks like:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;[codeblock 453]&lt;br /&gt;&lt;br /&gt;You can see that our required &lt;b&gt;afterReturning()&lt;/b&gt; method is what finally does the work that we were trying to implement.&amp;nbsp; And all of this with no changes to our original application!&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;big&gt;Well.... not exactly.&amp;nbsp; &lt;/big&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;While this is certainly a pretty low impact change to our application, the idea that it would not affect any existing code wasn&apos;t the actual reality for a couple of reasons.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&amp;nbsp;MemberService&lt;/b&gt; is no longer a &lt;b&gt;MemberService!&lt;/b&gt;&amp;nbsp; In about eleventy thousand places in my application, I had services that were wired with a dependency of our MemberService.&amp;nbsp; Each of these had a getter/setter that looked something like this:&lt;br /&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;[codeblock 454]&lt;br /&gt;&lt;br /&gt;With the changes that we have implemented, our MemberService&lt;/span&gt; is a completely different animal!&amp;nbsp; Every single one of my getters and setters failed since my MemberService is now actually of type &lt;b&gt;coldspring.aop.framework.ProxyFactoryBean&lt;/b&gt;.&amp;nbsp; I altered them all to have type &quot;any&quot; (in case I remove this AOP piece later!) and all works.&amp;nbsp; I suppose it is a worthwhile change, but it would be nicer if this change was truly transparent to my application. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;This one is the head scratcher, and as of the time of this blog posting I have no explanation whatsoever.... but a &lt;b&gt;Member&lt;/b&gt; isn&apos;t always a &lt;b&gt;Member&lt;/b&gt;?!?&amp;nbsp; In my &lt;b&gt;MemberService&lt;/b&gt;, I have a &lt;b&gt;getMember()&lt;/b&gt; method which returns a type &lt;b&gt;my.objects.Member&lt;/b&gt;.&amp;nbsp; In my initial testing I had no problems with this at all.&amp;nbsp; However, once I rolled it into production, there was a process that called the &lt;b&gt;MemberService.getMember() &lt;/b&gt;method that I had not hit in my initial tests.&amp;nbsp; When it was called I received the following exception:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;Message:The value returned from function fnct_&lt;/b&gt;&lt;div id=&quot;:1it&quot; class=&quot;ii gt&quot;&gt;&lt;wbr/&gt;&lt;b&gt;673EC50CBDBD5294E06289EE40D44A&lt;/b&gt;&lt;wbr/&gt;&lt;b&gt;BE() is not of type Member&lt;br /&gt;&lt;/b&gt;Our proxy MemberService creates a dynamic method that forwards requests onto the original target &lt;b&gt;getMember()&lt;/b&gt; method.&amp;nbsp; For whatever reason, in this one case, it was unable to validate that the returned object was indeed a &lt;b&gt;Member&lt;/b&gt;.&amp;nbsp; I modified my original &lt;b&gt;MemberService&lt;/b&gt; to make the returntype of &lt;b&gt;getMember()&lt;/b&gt; &quot;any&quot; an all is now working well.&amp;nbsp; If anyone has an explanation for that one I am all ears!&lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;Aside from those two issues, my new AOP functionality is now in production and working exactly as I had hoped.&amp;nbsp; Overall, I think that this is a very cool feature of ColdSpring, and one that I will definitely be making more use of moving forward.&lt;br /&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;br /&gt;&lt;br /&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=d2c0dcd3-0b5e-8640-8495-903100f55a7f&quot; /&gt;&lt;/div&gt;</description><pubDate>Mon, 07 Dec 2009 15:00:07 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/12/07/Setting-up-ColdSpring-AOP-and-interesting-behavior-with-return-types/</guid><category>ColdFusion,Technology</category></item><item><title>Talking through some current issues with ColdFusion Event Gateways</title><link>http://daveshuck.instantspot.com/blog/2009/11/09/Talking-through-some-current-issues-with-ColdFusion-Event-Gateways/</link><description>Normally on my blog I attempt to throw out some tip, trick, or nugget of some sort.&amp;nbsp; This time?&amp;nbsp; Not so!&amp;nbsp;&amp;nbsp; I am currently trying to find a solution to a problem at hand and am brainstorming the best way to handle a few things.&amp;nbsp; I am really just talking this out for my own benefit, but I would love to hear thoughts from others that have perhaps solved similar issues.&lt;br /&gt;&lt;br /&gt;On a project that I am currently engaged in I am leveraging ColdFusion Event Gateways which work as a subscriber to a SonicMQ JMS server.&amp;nbsp; My gateway instance listens for messages on the ESB (Enterprise Service Bus) on a particular destination name (topic/queue).&amp;nbsp; When it receives a message, it parses the XML that it received, and plays traffic cop pushing data into various services that need it.&amp;nbsp; I have this working flawlessly in my small development environment.&amp;nbsp; However, I have a couple of complexities ahead of me that I am having difficulty coming up with a good solution.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Running in the cloud - &lt;/b&gt;Our production environment will have any number of CF instances, not clustered, but rather running as isolated applications with a load balancer directing the requests using sticky sessions.&amp;nbsp; Our system will be bringing new instances on/off line as traffic traffic dictates.&amp;nbsp; I have yet to solve the issue of how to set up my JMS Event Gateway in this environment.&amp;nbsp; I definitely don&apos;t want 20 different listeners out there all doing the same work.&amp;nbsp; I have considered the idea of having some sort of a support database where a listener can insert a row with a specific JMS message ID and when any other server picks up a message with that ID it will see that it is already being acted upon and it can safely ignore it. There are a couple of negatives that I can see right off the bat.&amp;nbsp; First is that every single subscribed instance will have to pull in the same message and test to see whether or not it should be acted upon.&amp;nbsp; It just seems like a little bit of redundancy that shouldn&apos;t be there.&amp;nbsp; Secondly, there is a chance that two servers could pick up the same request within milliseconds of each other and both could end up doing the work.&amp;nbsp; Duplicate processing could not only be wasteful, but could also create some data integrity issues.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Different environments have different settings (dynamic config)&lt;/b&gt; - Right now in our development phase, we have a single config file with setting specific to our development JMS server (credentials, domain, URL, Initial Context Factory, etc).&amp;nbsp; However, soon I will need to have this process support a number of different environments: multiple dev environments, multiple integration environments, multiple QA environments, and eventually production.&amp;nbsp; Ideally it would be wonderful if I could find some way to load a specific config into the event gateway at server init time, but as of today I have _NO_ idea how to solve this one.&amp;nbsp; First, there is no real intrinsic indicator at the server level that lets it know what environment is currently running (yet anyway...) and secondly, ColdFusion event gateway architecture isn&apos;t conducive in any way to dynamically loading a specific config.&amp;nbsp; &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;So now I am counting on you CFML community.&amp;nbsp; Help me brain storm on this!&amp;nbsp; Do you have any thoughts/ideas that might help me here?&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=acb39c0d-d2f4-8647-b4f4-44e30f8e673e&quot; /&gt;&lt;/div&gt;</description><pubDate>Mon, 09 Nov 2009 16:28:07 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/11/09/Talking-through-some-current-issues-with-ColdFusion-Event-Gateways/</guid><category>ColdFusion,Technology,Java</category></item><item><title>Strange behavior with ColdFusion ExpandPath() when using Symbolic Links</title><link>http://daveshuck.instantspot.com/blog/2009/09/23/Strange-behavior-with-ColdFusion-ExpandPath-when-using-Symbolic-Links/</link><description>&lt;p&gt;I was playing around with the Quicksilver framework last night, and for some reason it was unable to find and instantiate my CFCs properly.&amp;nbsp; After digging into the framework a bit and determining where it was breaking, I discovered something strange about the way that ColdFusion interprets ExpandPath() when it exists in a directory that is defined as a symbolic link.&amp;nbsp; I am not sure if the same behavior exists on Macs, but I would imagine it does.&amp;nbsp; If someone could confirm that to be the case, I would be interested.&lt;br /&gt; &lt;br /&gt; For starters, I usually have a &apos;www&apos; directory in my user home directory. This way when I pass my user profile around from distro to distro, my development work is included in my home directory.&amp;nbsp; For ease of configuration I typically have a symbolic link in my OS that points &lt;strong&gt;/www/&lt;/strong&gt; ---&amp;gt; &lt;strong&gt;/home/dshuck/www/&lt;/strong&gt;.&amp;nbsp; Then when I am creating a new web project called &apos;davescode&apos;, I would put it in &lt;strong&gt;/home/dshuck/www/davescode&lt;/strong&gt;, but my Apache config would usually point to &lt;strong&gt;/www/davescode&lt;/strong&gt;.&amp;nbsp; For the past several years, this approach has worked will for me.&amp;nbsp; That is until last night when experimenting with Quicksilver.&amp;nbsp; &lt;br /&gt; &lt;br /&gt; When Quicksilver loads, it creates a list of service CFCs in the the application in such a way that if I had Foo.cfc in a directory &lt;strong&gt;&apos;com&apos; &lt;/strong&gt;in the root of my davescode site, it would look like &lt;strong&gt;/home/dshuck/www/davescode/com/Foo.cfc&lt;/strong&gt;.&amp;nbsp; When I initted the application, I was getting an error that&amp;nbsp; it couldn&apos;t find the CFC &lt;strong&gt;home/dshuckcom/Foo.cfc&lt;/strong&gt;.&amp;nbsp; Essentially what was happening is that it was getting the full path of the CFC and replacing the path to the root of the site with &amp;quot;&amp;quot;.&amp;nbsp; In a perfect world the value of the path after the string replace would have looked like &lt;strong&gt;com/Foo.cfc.&amp;nbsp; &lt;/strong&gt;Unfortunately that was not so.&amp;nbsp; Here&apos;s why!&lt;br /&gt; &lt;br /&gt; I put a test file called path.cfm in the root of my davescode site that considted of the following:&lt;br /&gt; &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfoutput&amp;gt;#ExpandPath(&amp;quot;./&amp;quot;)#&amp;lt;/cfoutput&amp;gt; &amp;lt;br/&amp;gt; &amp;lt;cfoutput&amp;gt;#ExpandPath(&amp;quot;/&amp;quot;)#&amp;lt;/cfoutput&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; The result was &lt;em&gt;very&lt;/em&gt; surprising!&lt;br /&gt; &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;/home/dshuck/www/davescode/ /www/davescode/&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; For some reason when you do ExpandPath(&amp;quot;/&amp;quot;) it looks at the symbolic link path, but when you do ExpandPath(&amp;quot;./&amp;quot;), it looks at the true file path.&amp;nbsp; For the life of me, I can&apos;t think of why that would be.&amp;nbsp; If anyone has an explanation, I would be all ears!&lt;/p&gt; &lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img class=&quot;zemanta-pixie-img&quot; alt=&quot;&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=49729c7f-e4fe-8ce3-a08f-2bd5d5e173f3&quot; /&gt;&lt;/div&gt;</description><pubDate>Wed, 23 Sep 2009 14:11:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/09/23/Strange-behavior-with-ColdFusion-ExpandPath-when-using-Symbolic-Links/</guid><category>ColdFusion,Technology,Linux</category></item><item><title>Solving java.lang.SecurityException: Seed must be between 20 and 64 bytes. Only 8 bytes supplied.</title><link>http://daveshuck.instantspot.com/blog/2009/05/08/Solving-javalangSecurityException-Seed-must-be-between-20-and-64-bytes-Only-8-bytes-supplied/</link><description>&lt;p&gt;Recently I have began working with JMS and ColdFusion, in which we are building a system that subscribes to an enterprise JMS server and picks up messages relevant to its needs and acts on them. I had my proof of concept working with the open source Apache ActiveMQ server and was very pleased with the results.&amp;nbsp; However, in our production environment, the powers that be decided to use the very non-free SonicMQ server.&lt;/p&gt; &lt;p&gt;As I tried to convert the event gateway over to the SonicMQ server, it failed on initialization with the following exception:&amp;nbsp; &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;javax.naming.NamingException [Root exception is java.lang.SecurityException: Seed must be between 20 and 64 bytes. Only 8 bytes supplied.]  at com.sonicsw.jndi.mfcontext.MFConnectionManager.connect(Unknown Source)  at com.sonicsw.jndi.mfcontext.MFConnectionManager.&amp;lt;init&amp;gt;(Unknown Source)  at com.sonicsw.jndi.mfcontext.MFConnectionManager.getManager(Unknown Source)  at com.sonicsw.jndi.mfcontext.MFContext.&amp;lt;init&amp;gt;(Unknown Source)  at com.sonicsw.jndi.mfcontext.MFContextFactory.getInitialContext(Unknown Source)  at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)  at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)  at javax.naming.InitialContext.init(InitialContext.java:223)  at javax.naming.InitialContext.&amp;lt;init&amp;gt;(InitialContext.java:197)  at examples.JMS.JMSConsumer.start(Unknown Source)  at examples.JMS.JMSGateway.startGateway(Unknown Source)  at coldfusion.eventgateway.GenericGateway.start(GenericGateway.java:118)  at coldfusion.eventgateway.EventServiceImpl$GatewayStarter.run(EventServiceImpl.java:1428)&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;In my research on this problem, I found several people reporting similar errors, each on CF8, and each talking to 3rd party tools.&amp;nbsp; Eventually I found the solution through an email discussion between one of the developers in my company and an Adobe developer.&amp;nbsp; Apparently in CF8, they added FIPS security, which disables the Sun JCE (encryption libraries).&amp;nbsp; To solve this error, you need to add the following line to your java.args in your jvm.config file in JRun.&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;-Dcoldfusion.disablejsafe=true&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;Now restart your server and try again!&lt;/p&gt;</description><pubDate>Fri, 08 May 2009 14:24:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/05/08/Solving-javalangSecurityException-Seed-must-be-between-20-and-64-bytes-Only-8-bytes-supplied/</guid><category>ColdFusion,Java</category></item><item><title>Making your application flow obvious in Mach-II with event-mappings</title><link>http://daveshuck.instantspot.com/blog/2009/04/11/Making-your-application-flow-obvious-in-MachII-with-eventmappings/</link><description>&lt;p&gt;I recently joined a company that makes use of Mach-II in a few applications.&amp;nbsp; Some of them were created as the developers were learning the framework and employ some obvious un-best practices.&amp;nbsp;&amp;nbsp; The team is made up of people from various skill levels, but I have noticed that about half of the team just absolutely cringes when they hear &amp;quot;Mach-II&amp;quot;.&amp;nbsp; They talk about how difficult it is to troubleshoot and how it is next to impossible to follow application flow.&amp;nbsp;&amp;nbsp; I was very surprised to hear that response, because I think one of the big benefits of using Mach-II is that I can look at a config XML and read the story of my application.&amp;nbsp;&amp;nbsp; I will touch on this in more detail in a bit.&lt;br /&gt; &lt;br /&gt; So the other day I had my first experience digging in deeply into one of they apps to solve a problem... and it took me &lt;em&gt;&lt;strong&gt;forever&lt;/strong&gt;&lt;/em&gt; to figure out where the hell anything was.&amp;nbsp; I started on the default home event, which only had a filter that announced other events, that had listeners that announced other events and so on until I was *&lt;em&gt;&lt;strong&gt;EIGHT&lt;/strong&gt;&lt;/em&gt;* events deep.&amp;nbsp; In each one of these announcements, I had to go find the listener/filter, look into the methods, and search for where I might be going next.&amp;nbsp; It suddenly became overtly clear why the other developers hate Mach-II.&lt;br /&gt; &lt;br /&gt; Now, back to why my config files tell a story... first of all, I can&apos;t think of many cases where an app needs to announce 8 events before it gets to a destination.&amp;nbsp; However, troubleshooting this would have been so much simpler if only the developer had been clear in the XML using event-mappings.&amp;nbsp; As a rule, if I ever alter the flow of my application from within a filter/listener, I &lt;em&gt;&lt;strong&gt;always&lt;/strong&gt;&lt;/em&gt; have an event-mapping that shows this in my config.&amp;nbsp; That way I can quickly skim the XML and know what possible exits I have.&amp;nbsp; In most cases, it should be pretty obvious where you are going based on that alone,&amp;nbsp; and you don&apos;t even need to open the CFCs to figure it out.&amp;nbsp; Although I certainly do use event-mapping for aliases, more often than not they will look like this:&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;event-mapping event=&amp;quot;SomeEvent&amp;quot; mapping=&amp;quot;SomeEvent&amp;quot; /&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;It serves no actual functinal purpose other acting as a means to document the flow. Does anyone else use the practice?&amp;nbsp; How do you keep the application flow obvious in your configuration files?&amp;nbsp;&lt;/p&gt; &lt;p&gt;I was talking to &lt;a href=&quot;http://www.aaronjlynch.com&quot;&gt;Aaron Lynch&lt;/a&gt; about this (who uses the same practice) and from that conversation I decided I would open this up for conversation.&amp;nbsp; What I would love to see is some type of optional setting in Mach-II that would enforce this so that all developer on a team had to use this methodology.&amp;nbsp;&amp;nbsp; Maybe something along the lines where when an event is announced from within a CFC and it hasn&apos;t been mapped in the XML it would barf up an exception?&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have no doubt that some people will hate this idea.&amp;nbsp; However, in the bigger picture I would like to see less people hating frameworks, and if we can make things more clear from a troubleshooting/maintanence perspective, I think that there would be less FUD!&lt;/p&gt; &lt;p&gt;Any thoughts on this?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Sat, 11 Apr 2009 18:46:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/04/11/Making-your-application-flow-obvious-in-MachII-with-eventmappings/</guid><category>ColdFusion</category></item><item><title>Interfaces in ColdFusion - I think I have finally come around on CFINTERFACE</title><link>http://daveshuck.instantspot.com/blog/2009/03/06/Interfaces-in-ColdFusion--I-think-I-have-finally-come-around-on-CFINTERFACE/</link><description>&lt;p&gt;I will admit it...&lt;br /&gt; &lt;br /&gt; When all the pre-ColdFusion 8 debate was swirling about whether or not to add interfaces into CFML, I didn&apos;t really get it.&amp;nbsp; It&apos;s true.&amp;nbsp; The only OOP I had ever really done was in CFML, ever having experienced how interfaces really come into play, and I think I fell into the the easy path of considering it worthless because I didn&apos;t take the time to understand it.&amp;nbsp; So very quietly, I was in the &amp;quot;we don&apos;t need it!&amp;quot; camp.&lt;br /&gt; &lt;br /&gt; Much has changed for me as a developer since that time.&amp;nbsp; I have gotten quite comfortable in Flex development, and working with Flex made me realize that Java is not really all that difficult to grasp for me now, and I am pretty comfortable getting around there too.&amp;nbsp; I have begun playing a bit with Groovy as well, so I have been exposed to much more since there actually *was* a debate about interfaces.&lt;br /&gt; &lt;br /&gt; So now that debate has long since died, and the pro-interface crowd won&amp;nbsp; - and then immediately decided that they didn&apos;t actually need interfaces after all - I realized yesterday that I finally get it!&lt;br /&gt; &lt;br /&gt; Before I go any further, I would like to give my definition of an interface, because I am sure there are still plenty of CF developers who are where I was just a short time ago with just a very loose grasp, if any, on the concept.&amp;nbsp; In fact, I am not sure that I am much beyond a loose grasp, but I will do my best to explain.&amp;nbsp; For those who already know all this, just bear with me here.&lt;br /&gt; &lt;br /&gt; In talking about interfaces with another developer on my team yesterday he asked how they are used.&amp;nbsp; Half joking, I replied &amp;quot;They aren&apos;t!&amp;nbsp; They don&apos;t *do* anything at all&amp;quot;.&amp;nbsp; What I meant by this is that you don&apos;t ever actually call an interface and your application never actually asks an interface to do anything.&amp;nbsp; The interface exists simply to enfore rules in your data model.&amp;nbsp; In essence it is a zero-tolerance &amp;quot;Object Gestapo&amp;quot; that makes sure that no one ever gets out of line.&amp;nbsp; An interface is truly little more than a contract that says &amp;quot;Any object that implements me must contain the things I define&amp;quot;.&amp;nbsp; In essence, I suppose you could think of it as a shell CFC that defines methods, arguments, and return types, that you can&apos;t actually call.&amp;nbsp; If I then define a CFC that implements that interface, it better damn well adhere to it strictly or the object gestapo comes down on you hard!&lt;br /&gt; &lt;br /&gt; So why this extra work right?&amp;nbsp; CF is a loosely typed language. Its status as an OOP language has been debated.&amp;nbsp; However, the fact of the matter is that most of the top slice of CFML developers are writing some really amazing object oriented applications.&amp;nbsp; Due to this, some of the more strict products from languages like Java might actually have some place in our work.&lt;br /&gt; &lt;br /&gt; Let me give a real world solution that might help solidify my swirling thoughts on the matter.&amp;nbsp; to give background on the environment I am working in, I recently began working for a relatively large insurance provider.&amp;nbsp;&amp;nbsp; Counting another 17 developers that are just being moved into ColdFusion from other languages, we have one of the larger ColdFusion development groups that I am aware of in my area.&amp;nbsp; Many of the developers work remotely, and we have several that are in other states.&amp;nbsp; Due to this, communication must be clear to keep everyone on the same page.&lt;br /&gt; &lt;br /&gt; A current project that is in the works is to move our entire policy system off of one third-party vendor to another. The APIs between the two are vastly different, however, we still need the same data available to us in our applications.&amp;nbsp; To make things more complicated, we will be moving one state at a time.&amp;nbsp; So effectively there will be two distinctly different policy systems in play until the last state is converted.&lt;br /&gt; &lt;br /&gt; My architectural approach to solving that problem is to use a PolicySystemFactory that returns the appropriate PolicySystem to me based on specific business rules.&amp;nbsp; Any PolicySystem will actually serve as an adapter to the specific API of its third-party system, but the methods that the PolicySystem object exposes to the application&amp;nbsp; *must* be consistent.&amp;nbsp; The application shouldn&apos;t really care which system it is talking to as long as the system is giving it the right data and doing taking the right action on data that is passed in.&lt;br /&gt; &lt;br /&gt; How do we ensure that we have the exact same API for not only the two current policy systems, but any future policy systems that we don&apos;t even know about yet?&amp;nbsp; &lt;br /&gt; &lt;br /&gt; Well, we could just make sure all developers know about it, and write it in some document hundreds of pages long that no one ever reads.&amp;nbsp; Then after both of those things fail, the developers will eventually figure it out as the application pukes in different areas as it is getting data in different shapes than it is expecting, or as it tries to use methods differently than the PolicySystem is expecting.&amp;nbsp; Eventually they will work this out.&lt;br /&gt; &lt;br /&gt; Or... You could do both of the above items (communicate &amp;amp; document) and save everyone a lot of trouble by establishing that any PolicySystem *must* adhere to rules established in an interface.&amp;nbsp; By taking this approach, there is no question whatsoever that the PolicySystem will not break your application by working differently than expected.&lt;br /&gt; &lt;br /&gt; How do you implement this approach? (really.. I didn&apos;t mean it as a pun)&lt;br /&gt; &lt;br /&gt; First, we would want to figure out exactly how a PolicySystem should be shaped.&amp;nbsp; In our ultra-simplified example, a PolicySystem must have three methods: &lt;strong&gt;getPolicy(id)&lt;/strong&gt; returning a Policy object, &lt;strong&gt;getPolicyAgent(Policy) &lt;/strong&gt;returning and Agent object, and &lt;strong&gt;getPoliciesByStatus(StatusId)&lt;/strong&gt; returning a structure of Policy objects&lt;br /&gt; &lt;br /&gt; This is what our Interface would look like:&lt;br /&gt; &lt;br /&gt; PolicySystemInterface.cfc&lt;br /&gt; &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfinterface&amp;gt;   &amp;lt;cffunction name=&amp;quot;getPolicy&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;Policy&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;id&amp;quot; type=&amp;quot;numeric&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt; &amp;lt;/cffunction&amp;gt;   &amp;lt;cffunction name=&amp;quot;getPolicyAgent&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;Agent&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;Policy&amp;quot; type=&amp;quot;Policy&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt; &amp;lt;/cffunction&amp;gt;   &amp;lt;cffunction name=&amp;quot;getPoliciesByStatus&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;Policy{}&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;StatusId&amp;quot; type=&amp;quot;numeric&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt; &amp;lt;/cffunction&amp;gt;   &amp;lt;/cfinterface&amp;gt; &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; As you can see above, we use the &amp;lt;cfinterface /&amp;gt; tag to define this CFC as an interface.&amp;nbsp; We then write our functions much like we would in a &amp;lt;cfcomponent /&amp;gt; keeping in mind that whatever we define must be used *exactly* the same way by any object that implements it.&amp;nbsp; So what would one of those objects look like?&amp;nbsp; Here is our old legacy policy system object.&amp;nbsp; Take a look at what is going on in line #1 in the &amp;lt;cfcomponent /&amp;gt; tag.&lt;br /&gt; &lt;br /&gt; &lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;OldLegacyPolicySystem.cfc&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfcomponent name=&amp;quot;OldLegacyPolicySystem&amp;quot; output=&amp;quot;false&amp;quot; extends=&amp;quot;AbstractPolicySystem&amp;quot; implements=&amp;quot;PolicySystemInterface&amp;quot;&amp;gt;  &amp;lt;cffunction name=&amp;quot;init&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;AbstractPolicySystem&amp;quot;&amp;gt;  &amp;lt;cfreturn super.init(&amp;quot;OldLegacyPolicySystem&amp;quot;) /&amp;gt; &amp;lt;/cffunction&amp;gt;  &amp;lt;cffunction name=&amp;quot;getPolicy&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;Policy&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;id&amp;quot; type=&amp;quot;numeric&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;  &amp;lt;!--- NOTE - In real life, we would use a service to create this bean, not instantiate it here!!! ---&amp;gt;  &amp;lt;cfset var Policy = CreateObject(&amp;quot;component&amp;quot;,&amp;quot;Policy&amp;quot;).init() /&amp;gt;    &amp;lt;!---   ########################################  In this area we would access policy info using the OldLegacyPolicySystem (however it does it!) and populate the Policy bean   ########################################  ---&amp;gt;    &amp;lt;cfreturn Policy/&amp;gt; &amp;lt;/cffunction&amp;gt;  &amp;lt;cffunction name=&amp;quot;getPolicyAgent&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;Agent&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;Policy&amp;quot; type=&amp;quot;Policy&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;  &amp;lt;!--- NOTE - In real life, we would use a service to create this bean, not instantiate it here!!! ---&amp;gt;  &amp;lt;cfset var Agent = CreateObject(&amp;quot;component&amp;quot;,&amp;quot;Agent&amp;quot;).init(arguments.Policy) /&amp;gt;    &amp;lt;!---   ########################################  In this area we would access Agent info using the OldLegacyPolicySystem and populate the Agent bean   ########################################  ---&amp;gt;    &amp;lt;cfreturn Policy/&amp;gt; &amp;lt;/cffunction&amp;gt;  &amp;lt;cffunction name=&amp;quot;getPoliciesByStatus&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;Policy{}&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;StatusId&amp;quot; type=&amp;quot;numeric&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;  &amp;lt;cfset var PolicyStruct = {} /&amp;gt;  &amp;lt;!---   ########################################  In this area we would load Policies using the OldLegacyPolicySystem and build a structure of them   ########################################  ---&amp;gt;   &amp;lt;cfreturn PolicyStruct /&amp;gt; &amp;lt;/cffunction&amp;gt; &amp;lt;/cfcomponent&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; You should notice that we have: &lt;strong&gt;&lt;br /&gt; &amp;nbsp;extends=&amp;quot;AbstractPolicySystem&amp;quot; implements=&amp;quot;PolicySystemInterface&amp;quot;&lt;br /&gt; &lt;br /&gt; &lt;/strong&gt;Two things are happening there.&amp;nbsp; First, we are extending an AbstractPolicySystem object that will hold common functionality among all PolicySystems.&amp;nbsp;&amp;nbsp; Ours looks like this: &lt;br /&gt; &lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;cfcomponent output=&amp;quot;false&amp;quot;&amp;gt; &amp;lt;cffunction name=&amp;quot;init&amp;quot; access=&amp;quot;public&amp;quot; output=&amp;quot;false&amp;quot; returntype=&amp;quot;AbstractPolicySystem&amp;quot;&amp;gt;  &amp;lt;cfargument name=&amp;quot;SystemName&amp;quot; type=&amp;quot;string&amp;quot; required=&amp;quot;true&amp;quot; /&amp;gt;  &amp;lt;cfset this.SystemName = arguments.SystemName /&amp;gt;  &amp;lt;cfreturn this /&amp;gt; &amp;lt;/cffunction&amp;gt; &amp;lt;/cfcomponent&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; For our test case, when we instantiate our PolicySystem we can quickly prove which one we are dealing with by looking at &lt;strong&gt;PolicySystem.SystemName&lt;/strong&gt;.&amp;nbsp; That said, your application shouldn&apos;t know or care.&lt;br /&gt; &lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;br /&gt; &lt;strong&gt;&lt;br /&gt; &lt;/strong&gt;By adding the &lt;strong&gt;implements&lt;/strong&gt; attribute we are ensuring that this PolicySystem plays by the rules we defined in our PolicySystemInterface.&amp;nbsp; No &amp;quot;ifs&amp;quot; &amp;quot;ands&amp;quot; or &amp;quot;but&amp;quot;s!&lt;br /&gt; &lt;br /&gt; So, this is the exercise that brought me around on CFINTERFACE.&amp;nbsp; What are your thoughts?&amp;nbsp; &lt;br /&gt; &lt;/span&gt;&lt;/p&gt; &lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img alt=&quot;&quot; class=&quot;zemanta-pixie-img&quot; src=&quot;http://img.zemanta.com/pixy.gif?x-id=04bb3470-2447-4c55-8b9b-205bd6c4cecd&quot; /&gt;&lt;/div&gt;</description><pubDate>Fri, 06 Mar 2009 17:03:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/03/06/Interfaces-in-ColdFusion--I-think-I-have-finally-come-around-on-CFINTERFACE/</guid><category>ColdFusion</category></item><item><title>Setting up Apache, OpenBD, Railo and ColdFusion - Part 4 - Installing Railo under Tomcat with Apache webserver</title><link>http://daveshuck.instantspot.com/blog/2009/02/09/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-4--Installing-Railo-under-Tomcat-with-Apache-webserver/</link><description>&lt;p&gt;This is Part 4 in an ongoing series demonstrating how to install OpenBlueDragon, ColdFusion, and Railo concurrently with all requests passing through the Apache webserver.&amp;nbsp; You will find links to all parts of this series at the bottom under &amp;quot;Related Content&amp;quot;&lt;br /&gt; &lt;br /&gt; In this post we will be building upon our existing environment in which we installed Apache webserver, Tomcat 6, OpenBlueDragon, and ColdFusion, by adding Railo to the mix.&amp;nbsp; If you have been following along thus far, we are well past the hard stuff at this point.&amp;nbsp; To install Railo, which is deployed as a java war file, we are going to repeat and slightly modify many of the steps that we took at the end of Part 2 when we installed OpenBD as a Tomcat web application.&lt;br /&gt; &lt;br /&gt; Let&apos;s start by setting up our hosts entry so that our new site resolves to localhost.railo, and set up the Apache webserver to listen for the request.&amp;nbsp; Open up /etc/hosts, and append &apos;localhost.railo&apos; (without quotes!) to the line that begins with 127.0.0.1.&amp;nbsp;&amp;nbsp; Next we want to create a new virtual host file for the site under Apache.&amp;nbsp; Do so like this:&lt;br /&gt; &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ cd /etc/apache2/sites-available   sudo gedit localhost.railo&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; Paste the following into that new file and save it.&lt;br /&gt; &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;VirtualHost *&amp;gt;  ServerName localhost.railo  JKMount /* worker1 &amp;lt;/VirtualHost&amp;gt; &lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; As we learned in Part 2, the line &amp;quot;JKMount /* worker1&amp;quot; is instructing apache to pass everything to the worker we defined in /etc/apache2/workers.properties.&amp;nbsp; That worker will then pass the request on to Tomcat port 8009, under which our application actually resides.&lt;br /&gt; &lt;br /&gt; Now that we have defined this site, we want to make sure that it gets included on our next Apache restart.&amp;nbsp; We do this by running the following:&lt;br /&gt; &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo a2ensite localhost.railo  Site localhost.railo installed; run /etc/init.d/apache2 reload to enable. &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; At this point, we need to make sure there is a an application set up in Tomcat to receive our request.&amp;nbsp; First, let&apos;s start by downloading&lt;/span&gt;the free Railo Server from &lt;a href=&quot;http://railo.ch/en/index.cfm?treeID=224&quot; target=&quot;_blank&quot;&gt;their download page&lt;/a&gt;.&amp;nbsp; Look toward the bottom of the page and download&amp;nbsp; &amp;quot;Railo Custom&amp;quot; and download railo-3.0.2.001.war. (or newer version if it is there).&amp;nbsp; Once we have the file downloaded, we will create a new directory for our application under Tomcat.&amp;nbsp; We will then copy the Railo war file into it from our download directory.&amp;nbsp; When we have the war file under /opt/tomcat6/webappas/localhost.railo/ we will extract it, and then safely delete the war file itself.&amp;nbsp; These steps can be seen here:&lt;br /&gt; &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo /opt/tomcat6/webapps/localhost.railo  sudo cp railo-3.0.2.001.war /opt/tomcat6/webapps/localhost.railo/  cd /opt/tomcat6/webapps/localhost.railo  sudo jar xvf railo-3.0.2.001.war   sudo rm railo-3.0.2.001.war&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; Since we now have the application in place, it is time to modify the Tomcat server config so that it knows to send the appropriate requests to it.&amp;nbsp; Do the following:&lt;br /&gt; &lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo gedit /opt/tomcat6/conf/server.xml&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; Look for the section that we added previously for our OpenBlueDragon localhost site &amp;quot;localhost.bd&amp;quot;.&amp;nbsp; We are going to copy that section, modifying the &amp;quot;name&amp;quot; and &amp;quot;docBase&amp;quot; attributes to match our new application and paste it just below the localhost.bd site.&amp;nbsp; When you are done they should look like this:&lt;br /&gt; &lt;/span&gt;&lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;Host name=&amp;quot;localhost.bd&amp;quot;  appBase=&amp;quot;webapps&amp;quot; unpackWARs=&amp;quot;true&amp;quot;   autoDeploy=&amp;quot;true&amp;quot; xmlValidation=&amp;quot;true&amp;quot; xmlNamespaceAware=&amp;quot;false&amp;quot;&amp;gt;   &amp;lt;Context path=&amp;quot;&amp;quot; docBase=&amp;quot;localhost.bd/&amp;quot; reloadable=&amp;quot;true&amp;quot; privileged=&amp;quot;true&amp;quot; antiResourceLocking=&amp;quot;false&amp;quot; anitJARLocking=&amp;quot;false&amp;quot; /&amp;gt; &amp;lt;/Host&amp;gt;  &amp;lt;Host name=&amp;quot;localhost.railo&amp;quot;  appBase=&amp;quot;webapps&amp;quot;  unpackWARs=&amp;quot;true&amp;quot;   autoDeploy=&amp;quot;true&amp;quot; xmlValidation=&amp;quot;true&amp;quot; xmlNamespaceAware=&amp;quot;false&amp;quot;&amp;gt;   &amp;lt;Context path=&amp;quot;&amp;quot; docBase=&amp;quot;localhost.railo/&amp;quot; reloadable=&amp;quot;true&amp;quot; privileged=&amp;quot;true&amp;quot; antiResourceLocking=&amp;quot;false&amp;quot; anitJARLocking=&amp;quot;false&amp;quot; /&amp;gt; &amp;lt;/Host&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;br /&gt; With all that done, we are ready to restart (or start) Apache, Tomcat and our new Railo site will be available at http://localhost.railo&lt;br /&gt; &lt;br /&gt; So with our original goal of being able to run the three CFML engines, it&apos;s time to see how we did....&lt;br /&gt; &lt;/span&gt;&lt;/p&gt; &lt;div class=&quot;youtube-video&quot;&gt;&lt;object height=&quot;400&quot; width=&quot;550&quot;&gt; &lt;param name=&quot;movie&quot; value=&quot;http://dl.getdropbox.com/u/101948/blog/movies/3-cfml-engines.swf&quot;&gt; &lt;/param&gt; &lt;embed src=&quot;http://dl.getdropbox.com/u/101948/blog/movies/3-cfml-engines.swf&quot; height=&quot;400&quot; width=&quot;550&quot;&gt; &lt;/embed&gt;  &lt;/object&gt;&lt;/div&gt;</description><pubDate>Tue, 10 Feb 2009 04:31:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/02/09/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-4--Installing-Railo-under-Tomcat-with-Apache-webserver/</guid><category>ColdFusion,Servers</category></item><item><title>Setting up Apache, OpenBD, Railo and ColdFusion - Part 3 - Installing ColdFusion and customizing the connector</title><link>http://daveshuck.instantspot.com/blog/2009/02/04/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-3--Installing-ColdFusion-and-customizing-the-connector/</link><description>&lt;p&gt;This is the third part in a series of posts on setting up ColdFusion, OpenBlueDragon, and Railo all on the same machine using Apache webserver to listen for all requests and direct traffic.&amp;nbsp; &lt;a href=&quot;http://daveshuck.instantspot.com/blog/2009/02/01/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-2--Installing-TomcatApacheOpenBD&quot;&gt;Part 2 can be found here&lt;/a&gt;.&amp;nbsp; You will find links to all parts of this series at the bottom under &amp;quot;Related Content&amp;quot;&lt;/p&gt; &lt;p&gt;With that said, this part in the series focuses on installing ColdFusion and configuring the webserver adapter in such a way that only specific Virtual Hosts will be set up to pass requests to the ColdFusion server.  First we want to start by creating a localhost site that is specific to ColdFusion 8 in Apache.&amp;nbsp; I tend to keep all my sites under /www which is actually symlinked to a &apos;www&apos; in my home directory. I find a few benefits in this.&amp;nbsp; First, I usually keep my home partition in shape and carry it around with me from distro to distro, so I always have my sites in tact with me.&amp;nbsp; Secondly since it is a symlink to my home and not in a system folder I don&apos;t need special permissions to write in it.&amp;nbsp; I will be following along this path, but if you keep your sites elsewhere, then you can adjust as necessary.  &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ mkdir /www/localhost.cf8&lt;/pre&gt;&lt;/div&gt;  Now, we will want to create an Apache virtual host definition for this site.&amp;nbsp; To do so, create a new configuration file like this: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo gedit /etc/apache2/sites-available/localhost.cf8&lt;/pre&gt;&lt;/div&gt;  Paste the the following, then save and close. &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;VirtualHost *&amp;gt;  ServerName localhost.cf8   &amp;lt;Directory /www/localhost.cf8/&amp;gt;   Options Indexes FollowSymLinks MultiViews   AllowOverride None   Order allow,deny   allow from all  &amp;lt;/Directory&amp;gt;  DocumentRoot /www/localhost.cf8 &amp;lt;/VirtualHost&amp;gt; &lt;/pre&gt;&lt;/div&gt;  Now we need to make sure that file is included when Apache starts, so run the following command which will make a symlink to the sites-enabled directory. &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$  sudo a2ensite localhost.cf8 Site localhost.cf8 installed; run /etc/init.d/apache2 reload to enable.&lt;/pre&gt;&lt;/div&gt;  As you can see from the localhost.cf8 configuration file, we are expecting our ServerName to be localhost.cf8, so we now need to add that entry to our hosts file. &amp;nbsp; &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo gedit /etc/hosts&lt;/pre&gt;&lt;/div&gt;  Append &amp;quot;localhost.cf8&amp;quot; (with no quotes!) to the line that begins with 127.0.0.1.&amp;nbsp; Save the file and close.  At this point you should be able to restart Apache and hit that empty site in your browser like this: &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-0-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;    Now that we have a site ready, it is time for us to install ColdFusion.&amp;nbsp; Once you have downloaded the .bin installation file from Adobe, browse to that directory in a terminal window.&amp;nbsp; You may need to chmod the file to be executable, then launch it like this:&amp;nbsp;  &lt;span style=&quot;padding: 0pt 10px 10px 0pt;&quot;&gt;&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ chmod +x coldfusion-801-lin.bin  sudo ./coldfusion-801-lin.bin&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;  Choose 1 for English.&amp;nbsp;  &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf8-install-01-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  After the welcome screen, hit enter to continue.&amp;nbsp; Next type &amp;quot;Y&amp;quot; and hit enter to agree to the terms and conditions.  We are now faced with the installation type prompt. For this example of setting up a development environment, we will choose option 3 &amp;quot;Developer Edition&amp;quot;  For our purposes we are going to choose the &amp;quot;Server configuration&amp;quot; option.&amp;nbsp; However, it should be noted that you could quite easily choole the J2EE WAR file option and install into Tomcat as we did with OpenBlueDragon in Part 2 of thise series. &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf8-install-02-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  Since we are installing from scratch, we will choose &amp;quot;No&amp;quot; (2) on the next option which is asking if there is an existing version of ColdFusion 8 installed on this machine.  For this installation we do not want any of the extra options to install such as Documentation, LiveCycle, Search Services, nor do we want to start on system init since this is on my laptop and I may not always want ColdFusion to start at boot.&amp;nbsp; So we will uncheck all options like you see in this image and continue. &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-03-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  We are going to accept the default installation path of /opt/coldfusion8  Again, since this is a fresh installation, we are going to say &amp;quot;No&amp;quot; (2) to the prompt asking if there are earlier versions of ColdFusion on this computer.  Now we start to work our way into the webserver configuration which will tie ColdFusion into Apache.&amp;nbsp; To start, choose &amp;quot;Add Web Server Configuration&amp;quot; (1) when prompted, then choose &amp;quot;Apache&amp;quot; (1).&amp;nbsp; In the following prompt asking for the Apache directory that contains your http.conf file, enter /etc/apache2 as you see in the picture below: &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-04-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  For the location of the Apache program binary file, enter /usr/sbin/apache2.&amp;nbsp; For the Start/Stop script, enter /etc/init.d/apache2.&amp;nbsp; You will see both of these choices here: &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-05-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  We now return to the first webserver configuration menu and this time choose &amp;quot;Continue with installation&amp;quot; (4).   Then we will need to enter the location of the webroot.&amp;nbsp; We are going to enter the directory of our new site /www/localhost.cf8 that we created above as you can see in the picture below.&amp;nbsp; We will also be asked which user we would like ColdFusion to run as.&amp;nbsp; I typically like to use my own user account for this so I don&apos;t end up with permissions issues where I have difficulty accessing files generated by ColdFusion &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-06-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  Now enter your admin password, and if you choose to user RDS, enter the&amp;nbsp; password for it as well.  It will now show you the general options you have selected and you will hit enter to start the actual installation.&amp;nbsp; Once it completes and prompts you to &amp;quot;Press Enter to exit the installer&amp;quot;, do so and then start the server with this: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo /opt/coldfusion8/bin/coldfusion start&lt;/pre&gt;&lt;/div&gt;  During this stage you should see messages that it is configuring the webserver successfully, assuming we entered everything properly above.&amp;nbsp;  &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-07.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-07-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  Once you are returned to a prompt, it is time to go customize the Apache connector stuff just a bit.&amp;nbsp; open the httpd.conf file like this: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo gedit /etc/apache2/httpd.conf&lt;/pre&gt;&lt;/div&gt;  In that you will find the connector stuff that ColdFusion added starting with a line: #JRun Settings.  Before we take the next steps, let me explain a bit what we are going to do.&amp;nbsp; We are going to seperate this into two pieces: the module loader, and the actual connector declaration.&amp;nbsp; As it stands right now, and request coming through the webserver would be handled by ColdFusion and we don&apos;t really want that.&amp;nbsp; To make it more granular, we are going to create an include file that can be added to any site that will add the connector only to that particular site.&amp;nbsp; With that said, let&apos;s walk through it. &amp;nbsp;  *Cut* (not copy!) these two lines of that connector info: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;# JRun Settings LoadModule jrun_module /opt/coldfusion8/runtime/lib/wsconfig/1/mod_jrun22.so&lt;/pre&gt;&lt;/div&gt;   Now we are going to paste those into a new file that will go in our mods-available directory.&amp;nbsp; Click on the &amp;quot;New&amp;quot; button in gedit and paste that text in.&amp;nbsp; Now save that file as&amp;nbsp; /etc/apache2/mods-available/cf8.load.  Now *cut* (not copy!) the remainder of the connector out that looks like this: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;IfModule mod_jrun22.c&amp;gt;     JRunConfig Verbose false     JRunConfig Apialloc false     JRunConfig Ignoresuffixmap false     JRunConfig Serverstore /opt/coldfusion8/runtime/lib/wsconfig/1/jrunserver.store     JRunConfig Bootstrap 127.0.0.1:51801     #JRunConfig Errorurl url &amp;lt;optionally redirect to this URL on errors&amp;gt;     #JRunConfig ProxyRetryInterval 600 &amp;lt;number of seconds to wait before trying to reconnect to unreachable clustered server&amp;gt;     #JRunConfig ConnectTimeout 15 &amp;lt;number of seconds to wait on a socket connect to a jrun server&amp;gt;     #JRunConfig RecvTimeout 300 &amp;lt;number of seconds to wait on a socket receive to a jrun server&amp;gt;     #JRunConfig SendTimeout 15 &amp;lt;number of seconds to wait on a socket send to a jrun server&amp;gt;     AddHandler jrun-handler .jsp .jws .cfm .cfml .cfc .cfr .cfswf &amp;lt;/IfModule&amp;gt;&lt;/pre&gt;&lt;/div&gt;  Create a new file named /etc/apache2/cf8connector. Pasted that text in and save the file.  Lastly, you may not have this issue, but I found that the DirectoryIndex attribute of Apache was not adding index.cfm to the list of default files. Due to this I actually added it to my httpd.conf. After all of the steps above, my httpd.conf file only has a single line: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;DirectoryIndex index.cfm&lt;/pre&gt;&lt;/div&gt;  Now... it is time to do just a little more Apache config and we are ready to go!&amp;nbsp; Rember that cf8.load mod file we created earlier?&amp;nbsp; Let&apos;s turn that on: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo a2enmod cf8&lt;/pre&gt;&lt;/div&gt;   Now, let&apos;s to add an include call to our localhost.cf8 virtual host configuration.&amp;nbsp; Open up /etc/apache2/sites-available/localhost.cf8 and add the &amp;quot;Include c8connector&amp;quot; line that you see below: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;VirtualHost *&amp;gt;         ServerName localhost.cf8          &amp;lt;Directory /www/localhost.cf8/&amp;gt;                 Options Indexes FollowSymLinks MultiViews                 AllowOverride None                 Order allow,deny                 allow from all         &amp;lt;/Directory&amp;gt;         DocumentRoot /www/localhost.cf8         Include cf8connector &amp;lt;/VirtualHost&amp;gt;&lt;/pre&gt;&lt;/div&gt;  Once you have saved that file, it is time to restart Apache and test out all of our hard work! &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;$ sudo /etc/init.d/apache2 restart&lt;/pre&gt;&lt;/div&gt;  Now, using your browser, go to http://localhost.cf8/CFIDE/administrator/ and you will see the following: &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-admin1.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/cf-install/cf-install-admin1-500.png&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  Now... if you are following along from earlier in this series, you should now be able to successfully connect to OpenBD at http://localhost.bd and ColdFusion 8 at http://localhost.cf8  On the next part of this series, we will bring Railo into the mix and finally have all three running on our system.&lt;/p&gt; &lt;p&gt;Next - &lt;a href=&quot;http://daveshuck.instantspot.com/blog/2009/02/09/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-4--Installing-Railo-under-Tomcat-with-Apache-webserver&quot;&gt;Part 4 Installing Railo under Tomcat with Apache webserver&lt;/a&gt;&lt;/p&gt;</description><pubDate>Thu, 05 Feb 2009 04:35:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/02/04/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-3--Installing-ColdFusion-and-customizing-the-connector/</guid><category>ColdFusion,Servers</category></item><item><title>Setting up Apache, OpenBD, Railo and ColdFusion - Part 2 - Installing Tomcat/Apache/OpenBD</title><link>http://daveshuck.instantspot.com/blog/2009/02/01/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-2--Installing-TomcatApacheOpenBD/</link><description>&lt;p&gt;This is the second part in a series of posts on setting up ColdFusion, OpenBlueDragon, and Railo all on the same machine using Apache webserver to listen for all requests and direct traffic.&amp;nbsp; &lt;a href=&quot;http://daveshuck.instantspot.com/blog/2009/02/01/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-1&quot;&gt;Part 1 can be found here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Remember, the steps below have some commands specific to Linux, and more specifically to Debian/Ubuntu, but the concepts in general should have at least some similarites across any supported platform, especially you Mac folks.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;To start out, we need to make sure that we have the Apache webserver installed with optional &amp;quot;dev&amp;quot; package.&amp;nbsp; Additionally, later on we will need to be compiling, so let&apos;s make sure that you have the build-essential package as well &lt;code&gt;$sudo apt-get install apache2 apache2-threaded-dev build-essential&lt;/code&gt;  Next I installed the Sun Java 6 JDK &lt;code&gt;$sudo apt-get install sun-java6-jdk&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Next you want to go download Tomcat.&amp;nbsp; I chose to use Tomcat 6, specifically v. 6.0.18, which the current release as of this posting.&amp;nbsp; Now, using a terminal cd into the directory where you saved the dowloaded file and do the following: &lt;code&gt;$ sudo cp apache-tomcat-6.0.18.tar.gz /opt/  $ cd /opt  $ sudo tar xvzf apache-tomcat-6.0.18.tar.gz  $ sudo mv apache-tomcat-6.0.18 tomcat6  $ sudo rm apache-tomcat-6.0.18.tar.gz&lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Next we will need to edit the Tomcat startup script, but to do so, we need to go get a little information first.&amp;nbsp; We need to ensure that we know what the current Java home is on your machine.&amp;nbsp; There are surely easier ways of accomplishing this, but here is the series of steps I took. &lt;code&gt;~$ which java /usr/bin/java  $ ls -l /usr/bin/java lrwxrwxrwx 1 root root 22 2009-01-30 23:00 /usr/bin/java -&amp;gt; /etc/alternatives/java  $ ls -l /etc/alternatives/java[return] lrwxrwxrwx 1 root root 36 2009-01-30 23:00 /etc/alternatives/java -&amp;gt; /usr/lib/jvm/java-6-sun/jre/bin/java &lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; From that last line I can see that the default Java lives at /usr/lib/jvm/java-6-sun/ (which too is a sym link, but that&apos;s ok!). Now that we have our Java home we can edit the Tomcat startup script &lt;code&gt;$sudo gedit /opt/tomcat6/bin/catalina.sh&lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Paste the following lines in just after the big comment block at the top. Make sure that if your Java path looked different than mine did, you will want to adjust accordingly. &lt;code&gt;JAVA_HOME=/usr/lib/jvm/java-6-sun  JRE_HOME=/usr/lib/jvm/java-6-sun/jre  JAVA_OPTS=&amp;quot;-server -Xms1024M -Xmx1024M -XX:PermSize=256m -XX:MaxPermSize=256m \ &amp;nbsp;&amp;nbsp;&amp;nbsp; -Duser.language=en -Duser.country=US -Dfile.encoding=UTF-8 \ &amp;nbsp;&amp;nbsp;&amp;nbsp; -Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl&amp;quot;  &lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Now we want to download the Apache Tomcat connector source so that we can pass requests from Apache webserver to Tomcat. This is the one I grabbed: &lt;a href=&quot;http://apache.org/dist/tomcat/tomcat-connectors/jk/source/&quot;&gt;http://apache.org/dist/tomcat/tomcat-connectors/jk/source/&lt;/a&gt;  Next you will want to browse to the directory that you downloaded that file into using in the terminal.  Next run: &lt;code&gt;$ tar xvzf tomcat-connectors-current-src.tar.gz  $ cd tomcat-connectors-1.2.27-src/native  $ ./configure --with-apxs=/usr/bin/apxs2  $ make  $ sudo make install&lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Now we will need to create a jk mod file to be included by Apache so that it loads the adapter when Apache starts. In your terminal cd to /etc/apache2/mods-available. In this directory we will create a file named jk.load. &lt;code&gt;$sudo gedit jk.load&lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; In that file pasted the following, then save and exit: &lt;code&gt;LoadModule jk_module /usr/lib/apache2/modules/mod_jk.so   # Where to find workers.properties  # Update this path to match your conf directory location (put workers.properties next to httpd.conf)  JkWorkersFile /etc/apache2/workers.properties  # Where to put jk shared memory  # Update this path to match your local state directory or logs directory  JkShmFile     /var/log/apache2/mod_jk.shm  # Where to put jk logs  # Update this path to match your logs directory location (put mod_jk.log next to access_log)  JkLogFile     /var/log/apache2/mod_jk.log  # Set the jk log level [debug/error/info]  JkLogLevel    info  # Select the timestamp log format JkLogStampFormat &amp;quot;[%a %b %d %H:%M:%S %Y] &amp;quot;&lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Now we want to create a symbolic link to this file in /etc/apache2/mods-enabled so that it is loaded when Apache starts. &lt;code&gt;$ cd /etc/apache2/mods-enabled  $ sudo ln -s ../mods-available/jk.load ./jk.load &lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Next we want to create a virtual host in Apache to catch the requests. We are going to create a new file in the sites-available directory. &lt;code&gt;$ cd /etc/apache2/sites-available  $ sudo gedit localhost.bd &lt;/code&gt;  In that file, paste the following, save, and exit: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;VirtualHost *&amp;gt;  ServerName localhost.bd  JKMount /* worker1 &amp;lt;/VirtualHost&amp;gt; &lt;/pre&gt;&lt;/div&gt;  &lt;br /&gt; &lt;br /&gt; Now we need to create a symbolic link to that file from sites-enabled so that it is available when apache2 starts. &lt;code&gt;$ cd /etc/apache2/sites-enabled  $ sudo ln -s ../sites-available/localhost.bd ./001-localhost.bd&lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Next we want to make sure that we can get to that site in a browser, so we are going to add &apos;localhost.bd&apos; to our hosts file. Open up /etc/hosts, and append &apos;localhost.bd&apos; (without quotes!) to the line that begins with 127.0.0.1.  Now we need to define that &amp;quot;worker1&amp;quot; that we just referenced above in the VirtualHost definition. We will do that by creating a workers.properties file in our apache2 directory. &lt;code&gt;$ cd /etc/apache2  $ sudo gedit workers.properties&lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Insert the following. Then save and exit: &lt;code&gt;# Define 1 real worker using ajp13  worker.list=worker1  # Set properties for worker1 (ajp13)  worker.worker1.type=ajp13  worker.worker1.host=localhost.bd  worker.worker1.port=8009  &lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; Next we want to create a webapp in Tomcat for Apache to send to.  &lt;code&gt;sudo gedit /opt/tomcat6/conf/server.xml&lt;/code&gt;   In that config, we need to define the localhost.bd site, or &apos;webapp&apos;.  Add the following: &lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;Host name=&amp;quot;localhost.bd&amp;quot;  appBase=&amp;quot;webapps&amp;quot;       unpackWARs=&amp;quot;true&amp;quot; autoDeploy=&amp;quot;true&amp;quot;       xmlValidation=&amp;quot;true&amp;quot; xmlNamespaceAware=&amp;quot;false&amp;quot;&amp;gt;   &amp;lt;Context path=&amp;quot;&amp;quot; docBase=&amp;quot;localhost.bd/&amp;quot; reloadable=&amp;quot;true&amp;quot; privileged=&amp;quot;true&amp;quot; antiResourceLocking=&amp;quot;false&amp;quot; anitJARLocking=&amp;quot;false&amp;quot;&amp;gt;  &amp;lt;/Context&amp;gt; &amp;lt;/Host&amp;gt; &lt;/pre&gt;&lt;/div&gt;  &lt;br /&gt; &lt;br /&gt; Now we need to create the local.bd directory under Tomcat. Note: as you get more comfortable and adventurous, you may want this to be a symbolic link to another place on your machine where your source resides, but for now we are keeping it as simple as we can. Once the directory is created, we will download the OpenBlueDragon war file and extract it. &lt;code&gt;$ sudo mkdir /opt/tomcat6/webapps/localhost.bd $ cd /opt/tomcat6/webapps/localhost.bd  $ sudo wget http://openbd.viviotech.net/downloader.cfm/id/64/file/openbd.war  $ sudo jar xvf openbd.war &lt;/code&gt;  &lt;br /&gt; &lt;br /&gt; And with that step, and after restarting Apache, and starting Tomcat, OpenBlueDragon will now be available. &lt;code&gt;$ sudo /etc/init.d/apache2 restart  $ /opt/tomcat6/bin/catalina.sh start&lt;/code&gt; &lt;br /&gt; &lt;br /&gt; Open up your browser and go to: http://localhost.bd/bluedragon/administrator&lt;br /&gt; &lt;br /&gt; You should be created with your OpenBD admin page like this:&lt;br /&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://dl.getdropbox.com/u/101948/OpenBDAdmin.png&quot;&gt;&lt;img alt=&quot;&quot; style=&quot;max-width: 800px;&quot; src=&quot;http://dl.getdropbox.com/u/101948/OpenBDAdmin-500.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Next: &lt;a href=&quot;http://daveshuck.instantspot.com/blog/2009/02/04/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-3--Installing-ColdFusion-and-customizing-the-connector&quot;&gt;Part 3 - Installing ColdFusion 8 and customizing the JRun connector&lt;/a&gt;&lt;/p&gt;</description><pubDate>Sun, 01 Feb 2009 07:34:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/02/01/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-2--Installing-TomcatApacheOpenBD/</guid><category>ColdFusion,Linux</category></item><item><title>Setting up Apache, OpenBD, Railo, and ColdFusion - Part 1</title><link>http://daveshuck.instantspot.com/blog/2009/02/01/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-1/</link><description>&lt;p&gt;This is Part 1 of a muilt-part blog post demonstrating how run OpenBlueDragon, Railo, and ColdFusion all on the same machine, and all using the Apache webserver with individual Virtual hosts using different CFML engines.&amp;nbsp; But, before we get into it, here is a little background.&lt;br /&gt; &lt;br /&gt; For the past several months now I have stepped over to Windows on my laptop after years of not using it regularly.&amp;nbsp; It was actually the first time I had actually used Vista, actually and was quite an interesting experience.&amp;nbsp; First, as much as I love the Linux environment, I really expected to loathe being in Windows daily.&amp;nbsp; I was surprised at how much Vista *didn&apos;t* suck.&amp;nbsp; With all the raging passion against it in general I suppose that I had low expectations, but nevertheless I really thought it was pretty decent in general.&amp;nbsp; However it has a more sluggish, constricting feel to it in comparison to Linux, so I have decided I have paid my dues and it is time to go back to using an OS that is truly fun to use, rather than one that just wasn&apos;t as crappy as I thought it would be.&amp;nbsp; &lt;br /&gt; &lt;br /&gt; After lots of experimentation with various flavors, hands-down Ubuntu is the most painless and most comfortable Linux distros for me personally.&amp;nbsp; My reasoning for that is vast and probably belongs in another blog entry, so I will attempt to keep from straying any further off the topic!&amp;nbsp; That said, last night I decided to try gOS which is a really neat distro built off of Ubuntu.&amp;nbsp; Although the UI is Gnome based, it has more of a Max 10.5.x feel to it.&amp;nbsp; I think Mac folks would feel right at home taking this environment for a spin.&lt;br /&gt; &lt;br /&gt; Immediately after the first boot of my shiny new OS I started trying to put my development environment back together.&amp;nbsp; I decided that I wanted to have ColdFusion, Railo, and OpenBD all on from the beginning, with all requests first passing through Apache httpd.&amp;nbsp; Quite some time ago, Aaron Lynch put together some steps to install Smith Project w/Tomcat/Apache, which we have used several times since, primarily setting up Railo. I am not sure I ever would have waded my way through it without his early experimentation and documentation.&amp;nbsp; On this iteration, I loosely followed those instructions, opting for several packages from the repos, and updated versions of software, and have documented my steps as the are somewhat different in areas. For my current environment, I first installed OpenBD.&amp;nbsp; I then followed this by installing ColdFusion and setting it up to user the default JRUN connector that is set up during the installation.&amp;nbsp; Lastly, I installed Railo as another webapp in Tomcat and tied that into Apache as well.&amp;nbsp; &lt;br /&gt; &lt;br /&gt; In the following posts, you will see these steps in detail.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; Next:&amp;nbsp; &lt;a href=&quot;http://daveshuck.instantspot.com/blog/2009/02/01/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-2--Installing-TomcatApacheOpenBD&quot;&gt;Part 2 - Installing Tomcat/Apache/OpenBD&lt;/a&gt;&lt;/p&gt;</description><pubDate>Sun, 01 Feb 2009 07:33:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/02/01/Setting-up-Apache-OpenBD-Railo-and-ColdFusion--Part-1/</guid><category>ColdFusion,Tips and Tricks,Servers</category></item><item><title>Customizing Illudium CFCGenerator XSL to fit your needs</title><link>http://daveshuck.instantspot.com/blog/2009/01/28/Customizing-Illudium-CFCGenerator-XSL-to-fit-your-needs/</link><description>&lt;p&gt;&lt;a href=&quot;http://ajlcom.instantspot.com&quot;&gt;Aaron&lt;/a&gt; and I are about to start work on a super-top-secret project (oops! Man I suck at secrets) in which we will be making use of Amazon ec2 and SimpleDB platforms using an Apache/Tomcat/OpenBD setup.  Considering the fact that in spite of the coolness of amazon services in production, it seems to be somewhat of a problematic platform to develop on.  &lt;br /&gt; &lt;br /&gt; So, until we have a a somewhat functional alpha release, we probably will do all the development that we can on local setups.  One of the immediate questions was in regards to how we would set up our CFC data model.  We tend to be fans of the Service/Bean/DAO/Gateway approach, but things change a bit when it comes to using Amazon SimpleDB.  We came to a decision that our best bet would be to have abstract DAO/Gateway classes that would in turn call the appropriate specific DAO/Gateway classes, so if we are working in development the path would be: Service--&amp;gt; AbstractDAO--&amp;gt; MySQL-DAO and in production it would be Service--&amp;gt; AbstractDAO--&amp;gt; Amazon-DAO.  To make the change only need to alter a ColdSpring property &amp;quot;databasetype&amp;quot; from &amp;quot;mysql&amp;quot; to &amp;quot;amazonbd&amp;quot;.  Notice the &amp;quot;BD&amp;quot; at the end of Amazon?  That is because this is not only an Amazon data object, but one that is actually designed for use with OpenBD to make use of the &amp;lt;cfquery dbtype=&amp;quot;amazon&amp;quot; /&amp;gt; &lt;cfquery datatype=&quot;amazon&quot;&gt; functionality!  Down the line we may add other specific subclasses as well as we need.&lt;br /&gt; &lt;br /&gt; One other approach that Aaron and I live and die by in our objects is to steer clear of custom code into our generated CFCs.  If you ever make changes to your database or objects in general that require you to re-generate them, it can be a real pain in the ass to make sure that you don&apos;t overwrite custom code that you spent precious hours on.  Our solution to this is to have all of our Bean/DAO/Gateway/Objects extend base classes so that if you have a UserDAO.cfc there would also be a BaseUserDAO.cfc which would be generated as an empty object.  We can then safely stuff all sorts of custom functionality in that base object, such as hasMany relationships/methods, etc, and then later regenerate the DAO itself on a whim, typically without repercussions whatsoever.&lt;br /&gt; &lt;br /&gt; With all of this functionality, we now end up with a ton of CFCs in each package, but the flexibility gained is well worth it.  Just how many?  Well in the example of a User, we would have:&lt;br /&gt; &lt;/cfquery&gt;&lt;/p&gt; &lt;ul&gt;     &lt;li&gt;User&lt;/li&gt;     &lt;li&gt;BaseUser&lt;/li&gt;     &lt;li&gt;UserService&lt;/li&gt;     &lt;li&gt;BaseUserService&lt;/li&gt;     &lt;li&gt;UserDAOAbstract&lt;/li&gt;     &lt;li&gt;BaseUserDAO&lt;/li&gt;     &lt;li&gt;UserDAOMySQL&lt;/li&gt;     &lt;li&gt;UserDAOAmazonBD&lt;/li&gt;     &lt;li&gt;UserGatewayAbstract&lt;/li&gt;     &lt;li&gt;BaseUserGateway&lt;/li&gt;     &lt;li&gt;UserGatewayMySQL&lt;/li&gt;     &lt;li&gt;UserGatewayAmazonBD&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For those that have used and know Illudium, you know that the templates it comes with don&apos;t fit these patterns!&amp;nbsp; I decided that I would set out to *make* it fit.&amp;nbsp; &lt;br /&gt; &lt;br /&gt; Of course I took the first tool I could grab in my toolbox - my sledgehammer - and started hacking into the Flex code trying to figure out what exactly I could change to make this work.&amp;nbsp; After more investigative work than I would like to admit, I realized I didn&apos;t need my sledgehammer at all!&lt;br /&gt; &lt;br /&gt; Brian Rinaldi has written such a flexible tool that I needed to do no more than create a new set of XSL templates to fit my needs and the rest would all fall in place.&amp;nbsp; If you look in the illudium code under cfcgenerator/xsl, you will find a folder named &amp;quot;projects&amp;quot;.&amp;nbsp; For some reason it never hit me previously what populated the &amp;quot;Template:&amp;quot; dropdown in the UI, but this list is generated from directories that lie under &amp;quot;projects&amp;quot;.&amp;nbsp; I then took a copy of the default XSL templates and put them in a new directory named &amp;quot;subclassed_data&amp;quot; since that is kind of the general goal of this.&amp;nbsp; By adding new XSL docs,&amp;nbsp; modifying the existing ones, and then making sure all the files I wanted to generate were listed in yac.xml, I easily acheived what I was after.&amp;nbsp; Here is the end product of XSL...&lt;br /&gt; &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/illudiumxsl-full.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/illudiumxsl-small.jpg&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; Really the only limitation I came across is that I was never happy with the casing that I ended up with.&amp;nbsp; We typically use camel casing in our objects like UserDaoMysql.&amp;nbsp; Given the way that Illudium works it would come out as UserDaomysql.&amp;nbsp; Considering that fact, I opted for making the end products of my CFCs all lower case.&amp;nbsp; Thankfully with ColdSpring I never actually see the casing of my filenames, so I think I can live with that.&amp;nbsp; To make this happen, I ended up changing the only line of the Illudium codebase so that it would force lowercase to the filenames that it saved.&lt;br /&gt; &lt;br /&gt; At this point, the only remaining thing that I may do is alter the Illudium UI.&amp;nbsp; Why?&amp;nbsp; Take a look at this!&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://dl.getdropbox.com/u/101948/blog/images/illudiumtabs-full.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://dl.getdropbox.com/u/101948/blog/images/illudiumtabs-small.jpg&quot; style=&quot;max-width: 800px;&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><pubDate>Wed, 28 Jan 2009 19:18:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2009/01/28/Customizing-Illudium-CFCGenerator-XSL-to-fit-your-needs/</guid><category>ColdFusion</category></item><item><title>Dependent objects made even easier in Mach-II 1.6</title><link>http://daveshuck.instantspot.com/blog/2008/07/23/Dependent-objects-made-even-easier-in-MachII-16/</link><description>&lt;p&gt;In case you were wondering if Mach-II could get any cooler, the answer is *yes*!&lt;br /&gt;&lt;br /&gt;For a few versions now, Mach-II has added the ability to inject ColdSpring beans in to your framework components (listeners, plugins, and filters) by use the parameter resolveMachIIDependencies when instantiating the ColdSpring plugin or property. &lt;br /&gt;&lt;br /&gt;Take this example... Say that I have a LoginListener.cfc that is dependent on a ColdSpring bean LoginService that lives in our /com directory.  I would first define that bean in our ColdSpring config like this: [codeblock 178]&lt;br /&gt;&lt;br /&gt;Then, in our LoginListener we would need to create a setter that matched the Bean that we have defined in ColdSpring like so: [codeblock 179]&lt;br /&gt;&lt;br /&gt;By taking these two actions, and insuring that your LoginService as an init() method as a constructor, when you initialize your application, &lt;strong&gt;variables.LoginService&lt;/strong&gt; will automatically be available to you as an instance of your LoginService bean.  That alone was pretty dang cool.  &lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;But wait there&apos;s more!&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;With Mach-II 1.6, this process has become even less cumbersome.  In some CFML tags, you can add unexpected attributes without throwing exceptions and are in essence ignored to offer a better solution for managing dependent objects.  By default, Mach-II will look for a &quot;depends&quot; attribute in your &lt;cfcomponent&gt; tags, which can contain a comma separated list of your dependencies.  For our simple LoginListener, our tag would look like this:&lt;/cfcomponent&gt; [codeblock 180]&lt;br /&gt;&lt;br /&gt;Now, instead of repetitive getters/setters, just by merely having that attribute, our LoginListener will now contain the method &lt;strong&gt;getLoginService()&lt;/strong&gt; which will return an instance of the LoginService.  That is just ridiculously easy!&lt;br /&gt;&lt;br /&gt;As I said, the attribute actually accepts a comma separated list, so as we add dependencies, our &lt;cfcomponent&gt; tag might look more like this:&lt;/cfcomponent&gt; [codeblock 181]&lt;br /&gt;&lt;br /&gt;If you have made it this far, you have probably deducted that we will now have access to &lt;strong&gt;getLoginService()&lt;/strong&gt;, &lt;strong&gt;getUserService()&lt;/strong&gt;, and &lt;strong&gt;getLoggingService()&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;As I mentioned earlier, Mach-II will look for the attribute &quot;depends&quot; by default, but you can customize it to use other attribute names if you wish. You can find that information and &lt;a href=&quot;http://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/FAQUsingNewColdspringProperty&quot;&gt;more on the Mach-II wiki&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;</description><pubDate>Wed, 23 Jul 2008 14:39:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2008/07/23/Dependent-objects-made-even-easier-in-MachII-16/</guid><category>ColdFusion</category></item><item><title>Related checkbox validation with JQuery</title><link>http://daveshuck.instantspot.com/blog/2008/07/16/Related-checkbox-validation-with-JQuery/</link><description>&lt;p&gt;I was given a problem yesterday where I needed to do the following client-side validation.  If a user selects a checkbox that they wish to enable credit card transactions, I need to display a panel of specific credit card companies and they need to select at least one before submitting.&lt;/p&gt; &lt;p&gt;If you think about writing the JS to do this without a library it is a somewhat lengthy task.  In essence, you would need to do some type of an onsubmit function on your form, check the value of the key checkbox.  If it was checked, check the value of each credit card checkbox to see if the user had selected one of the children.  After writing this in JQuery, I thought it might be worth demonstrating what an easy task this is.&lt;/p&gt; &lt;p&gt;Let&apos;s start with the specific part of my form that has my checkboxes:&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;label for=&amp;quot;RequireCCInfo&amp;quot;&amp;gt;Require Credit Card Information?&amp;lt;/label&amp;gt; &amp;lt;input name=&amp;quot;RequireCCInfo&amp;quot; id=&amp;quot;RequireCCInfo&amp;quot; value=&amp;quot;1&amp;quot; type=&amp;quot;checkbox&amp;quot;&amp;gt; &amp;lt;div id=&amp;quot;CreditCardCompanyPanel&amp;quot;&amp;gt;  &amp;lt;div&amp;gt;   &amp;lt;input id=&amp;quot;ccAmex&amp;quot; class=&amp;quot;ccCheckBox&amp;quot; value=&amp;quot;1&amp;quot; type=&amp;quot;checkbox&amp;quot;&amp;gt;   &amp;lt;label for=&amp;quot;ccAmex&amp;quot;&amp;gt;American Express&amp;lt;/label&amp;gt;  &amp;lt;/div&amp;gt;  &amp;lt;div&amp;gt;   &amp;lt;input id=&amp;quot;ccVisa&amp;quot; class=&amp;quot;ccCheckBox&amp;quot; value=&amp;quot;1&amp;quot; type=&amp;quot;checkbox&amp;quot;&amp;gt;   &amp;lt;label for=&amp;quot;ccVisa&amp;quot;&amp;gt;Visa&amp;lt;/label&amp;gt;  &amp;lt;/div&amp;gt;  &amp;lt;div&amp;gt;   &amp;lt;input id=&amp;quot;ccDiscover&amp;quot; class=&amp;quot;ccCheckBox&amp;quot; value=&amp;quot;1&amp;quot; type=&amp;quot;checkbox&amp;quot;&amp;gt;   &amp;lt;label for=&amp;quot;ccDiscover&amp;quot;&amp;gt;Discover&amp;lt;/label&amp;gt;  &amp;lt;/div&amp;gt;  &amp;lt;div&amp;gt;   &amp;lt;input id=&amp;quot;ccMc&amp;quot; class=&amp;quot;ccCheckBox&amp;quot; value=&amp;quot;1&amp;quot; type=&amp;quot;checkbox&amp;quot;&amp;gt;   &amp;lt;label for=&amp;quot;ccMc&amp;quot;&amp;gt;Master Card&amp;lt;/label&amp;gt;        &amp;lt;/div&amp;gt; &amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;There is nothing too notable in all of that other than the fact that you should notice that I have added a class &amp;quot;ccCheckBox&amp;quot; to all of my dependent checkboxes.  I will explain more on that in a bit, but I wanted to point out that it is there.  You will also notice that I am not doing anything in the way of hiding the &amp;quot;CreditCardCompanyPanel&amp;quot; div.  We need to determine at request time whether that will be hidden or not based on whether the &amp;quot;RequireCCInfo&amp;quot; checkbox is checked.&lt;/p&gt; &lt;p&gt;Now, here is the fun part...  I am including the JS that I use for this task below:&lt;div class=&quot;code&quot; &gt;&lt;pre&gt;&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;  (document).ready(function(){  $(&amp;quot;#RequireCCInfo&amp;quot;).change(function(){   toggleCreditCardCompanyPanel();  });    function toggleCreditCardCompanyPanel() {   if ($(&amp;quot;#RequireCCInfo&amp;quot;).attr(&amp;quot;checked&amp;quot;) == true)  $(&amp;quot;#CreditCardCompanyPanel&amp;quot;).show();    else $(&amp;quot;#CreditCardCompanyPanel&amp;quot;).hide();  }  $(&amp;quot;#SaveButton&amp;quot;).click(function(){   var pass = false;   if ($(&amp;quot;#RequireCCInfo&amp;quot;).attr(&amp;quot;checked&amp;quot;) == true){    $(&amp;quot;.ccCheckBox&amp;quot;).each(function() {                   if ($(this).attr(&amp;quot;checked&amp;quot;) == true) pass = true;               });   }   else pass = true;   if (pass) $(&amp;quot;#frmMyForm&amp;quot;).submit();   else alert(&apos;You must select at least on credit card company if &amp;quot;Require Credit Card Information&amp;quot; is checked.&apos;);  });   toggleCreditCardCompanyPanel(); }); &amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;First, by using the $(document).ready() function we are telling JQuery to run this JS once the DOM has been completely loaded.  Let&apos;s look at each section within that ready() block...&lt;/p&gt; &lt;p&gt;The first thing you will see is the $(&amp;quot;#RequireCCInfo&amp;quot;).change() method.  JQuery gives us the concept of binding a listener to an element.  For our example, this listener says that anytime that an element with an ID of &amp;quot;RequireCCInfo&amp;quot; is changed, that we will run the code in its function().  You will see that anytime our &amp;quot;RequireCCInfo&amp;quot; checkbox is changed we are going to run a function called toggleCreditCardCompanyPanel().   As you can see we have that method defined immediately after our &amp;quot;RequireCCInfo&amp;quot; checkbox.&lt;/p&gt; &lt;p&gt;In our toggleCreditCardCompanyPanel() method, we are making the decision as to whether or not our &amp;quot;CreditCardCompanyPanel&amp;quot; will be displayed based on whether our user has decided to check the box labeled &amp;quot;Require Credit Card Information?&amp;quot;.   By using the JQuery selectors we are in essence saying:  If a checkbox with an ID of &amp;quot;RequireCCInfo&amp;quot; is checked, display an element with the ID &amp;quot;CreditCardCompanyPanel&amp;quot;.  Otherwise we will hide this element.&lt;/p&gt; &lt;p&gt;Next comes our validation on form submit... and pretty cool stuff!&lt;/p&gt; &lt;p&gt;Basically I have added a listener which is bound to our submit button with the ID of &amp;quot;SaveButton&amp;quot; which will submit our form &amp;quot;frmMyForm&amp;quot;.   Anytime that this button is clicked, we will run the code in the function() block.   We start this function by setting a value pass=false.  We will use this variable to determine whether our form has passed validation.  Next we get just a small taste of the magic of JQuery selectors.    First, as we did in the toggleCreditCardCompanyPanel() function, we are determining if the element with the ID of &amp;quot;RequireCCInfo&amp;quot; is checked.  If so, by using the each() function, we are going to loop through all elements on the page with the class &amp;quot;ccCheckBox&amp;quot; (remember that from above?).  In each iteration of the loop we are going to determine if the element has been checked.  If so, we are going to set pass=true since we know that our validation has passed.&lt;/p&gt; &lt;p&gt;Lastly, now that we have determined that our form is either going to pass/fail, we take the appropriate action.  If pass==fail, we are simply going to alert a message telling the user that if they are going to enable credit cards that they have to choose at least one credit card company.  Otherwise, we are going to call the submit() method on our form.&lt;/p&gt; &lt;p&gt;I almost took the time to write out the equivalent of this in POJS (plain old JavaScript) to show how much easier life is with JQuery, but I realized I didn&apos;t have the time, patience, or will.  JQuery has spoiled me!&lt;/p&gt;</description><pubDate>Wed, 16 Jul 2008 14:41:00 GMT</pubDate><guid>http://daveshuck.instantspot.com/blog/2008/07/16/Related-checkbox-validation-with-JQuery/</guid><category>ColdFusion,Javascript,Tips and Tricks</category></item></channel></rss>