Dan's Shortstag:dansshorts.com,2024:/Musings of a ColdFusion Coder and all-around nice guy.Mango 1.7REFinding your voiceurn:uuid:60441209-D8B3-15B9-C5652BADF75C247B2013-09-30Thh:09:ss-05002013-12-17Thh:12:ss-0600Daniel Short
<p>I've lost mine, and am trying to find it again. I loved when I was blogging regularly, and being an active part of a thriving community. Over the last few years, that has slipped away from me. I haven't made a blog post in ages, and don't feel like I'm much a part of any community at all.</p>
<p>I'm going to make an effort to get back into that community. I'm going to try to blog more regularly, get back on the social networks where you guys are hanging out, and generally be a part of the conversation. I need to feel like this is something that I can still enjoy (programming, problem solving, and camaraderie with a great group of developers).</p>
<p>So here's to hoping that I can kick it up a notch, and find the voice I've lost.</p>
Easy Thread Throttling in ColdFusionurn:uuid:961712FA-AEA8-5D98-C5C30DBB3DFE15862013-05-10Thh:05:ss-05002013-05-10Thh:05:ss-0500Daniel Short
<p>I do a <em>lot</em> of large processing tasks at LandsofAmerica, and in order to get these scheduled operations to complete in any reasonable amount of time I use the <cfthread> tag to spin off multiple processing threads at a time. Unfortunately, some of these threads take longer to complete than it does to spin up another 5,000 threads in the queue. Once you break that thread limit, ColdFusion to stop accepting new threads and will throw an exception. So I use the method below to make sure that I don't spin up too many threads at one time.</p>
<p>So the trick is to create each thread with a unique name, keep track of those names, and wait for each batch of threads to finish before starting the next batch. And here's your sample code:</p>
<pre><code>/*
We need to keep track of the names of our threads
in order to make sure that we limit our processing
appropriately.
*/
listingThreadNames = "";
/*
And just for fun, we'll create a variable to keep
track of how many threads we want to spin off at any
one time.
*/
numberOfThreads = 10;
/* Loop and start creating threads */
for(i = 1; i LTE 100; i++){
/*
Create a thread name that we'll use to create
the thread and keep track of it. Make sure that
this is unique, or you'll get errors with duplicate
thread names
*/
threadName = "MyThread_#i#";
listingThreadNames = ListAppend(listingThreadNames, threadName);
thread
name = threadName
action = "run"
id = i {
//Do some amazing stuff here
sleep(5000);
}
/* If we've reached the number of defined threads, wait until they all finish. */
if(
listingThreadNames NEQ ""
AND ListLen(listingThreadNames) EQ numberofThreads
){
writeOutput("Waiting on the following threads to finish: #listingThreadNames#<hr />");
/* Join up the threads, which will cause a pause until all the threads are done */
thread
action="join"
name="#listingThreadNames#";
/* Clear out the thread names for use in the next iteration of the loop */
listingThreadNames = "";
}
}
</code></pre>
Meet me at cf.Objective()urn:uuid:49C9A42D-1D09-2C37-5F44BED12C1D83832011-03-15Thh:03:ss-05002013-08-14Thh:08:ss-0500Daniel Short
<p>Today I posted on Twitter that I would need to re-evaluate my friendship with anyone who couldn’t make it to cf.Objective(). But alright alright… I’ll still be your friend, even if you don’t make it to cf.Objective. But you should… I just finished working up my schedule, and I’m once again excited to attend a conference. I’ve been “meaning to attend MAX again” for years, but the last few times I’ve been it’s seemed more a social event, and less an “inspire me to build great things” event. But I still remember hanging out with Jared, Sean, Simeon, and “the rest of the gang” after the first cf.Objective() conference I attended. </p>
<p>After that first cf.Objective() conference is when I first started digging deep into OO development, and when I feel I really started becoming a “programmer” and not just a “developer”. The last few years have been very stagnant for me, since I’ve spent almost all of my time maintaining and attempting to improve or refactor legacy applications. Well it’s time to throw my hat back in the ring and go get some smarts.</p>
<p>So here’s a list of everything I’m currently set to attend at cf.Objective(). If you’re able to make it, please find me and say hello.</p>
<ul>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/undocumented-and-off-script-coldfusion-ehcache/">Undocumented and Off Script: ColdFusion & Ehcache</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/code-deployment-shouldnt-only-be-ftp-using-ant-to-automate-your-build-process/">Code Deployment Shouldn’t Only Be FTP - Using ANT to Automate Your Build Process</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/coldbox-platform-30/">ColdBox Platform 3.0</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/forms-that-dont-suck-quick-easy-clean-forms-and-data/">Forms That Don’t Suck (Quick, Easy, & Clean Forms and Data)</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/refactoring-a-legacy-application-to-an-mvc-framework/">Refactoring a Legacy Application to an MVC Framework</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/designing-for-scalability-in-coldfusion/">Designing for Scalability in ColdFusion</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/write-a-test-once-repeat-forever-you-dont-have-to-be-a-unit-testing-guru/">Write a Test Once; Repeat Forever – You Don’t Have to Be a Unit Testing Guru</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/replace-your-iron-with-a-cloud/">Replace Your Iron with a Cloud</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/holistic-program-quality-and-technical-debt/">Holistic Program Quality and Technical Debt</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/database-performance-tuning/">Database Performance Tuning</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/pinpointing-and-resolving-coldfusion-performance-issues/">Pinpointing and Resolving ColdFusion Performance Issues</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/application-intrusion-detection-and-tracking/">Application Intrusion, Detection and Tracking</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/just-mock-it-leveraging-mock-objects/">Just Mock It! : Leveraging Mock Objects</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/aop-for-you-and-me/">AOP For You and Me</a></li>
<li><a href="http://www.cfobjective.com/index.cfm/sessions/intro-to-angularjs-javascript-done-right/">Intro to AngularJS, JavaScript Done Right</a></li>
</ul>
<p>At the time that I’m writing this there are still 8 sessions still listed as TBA, so things may change. However, you can already see that there is an extremely diverse range of topics, from unit testing, to JavaScript frameworks, and automated deployment.</p>
<p>Check out the <a href="http://www.cfobjective.com/index.cfm/schedule/">schedule</a> and then <a href="https://www.bestmeetings.com/registration/cfobjective/">register</a> to get your own heavy dose of awesomeness.</p>
<p>Looking forward to seeing you there!</p>
Installation Wide contentRenderer for MuraCMSurn:uuid:EC195271-1D09-2C37-5F787E02D082C4122011-03-13Thh:03:ss-05002013-08-14Thh:08:ss-0500I have a fairly large Mura installation, with a good number of sites on it. I have some customizations that I'd like to be pushed out across all of the sites in my installation. For example, I've changed the way the dspPrimaryNav function works, so that I can prevent child pages from being displayed. Unfortunately, as flexible and customizable as Mura is, there is no good to make global changes to the `contentRenderer.cfc` without losing those changes everytime you perform an update to your core files.Daniel Short
<p>I have a fairly large Mura installation, with a good number of sites on it. I have some customizations that I’d like to be pushed out across all of the sites in my installation. For example, I’ve changed the way the dspPrimaryNav function works, so that I can prevent child pages from being displayed. Unfortunately, as flexible and customizable as Mura is, there is no good to make global changes to the <code>contentRenderer.cfc</code> without losing those changes everytime you perform an update to your core files.</p>
<p>To make this happen, we’re going to use the flexibility of extending components to create a custom <code>contentRenderer.cfc</code> that all sites in our installation will use. So first, we’ll create a directory at the root of our Mura installation called <code>custom</code>. In here we’re going to place all global custom functions we want to override. Here’s mine:</p>
<pre><code><cfcomponent extends="mura.content.contentRenderer">
<cfset this.jslib="jquery"/>
<cfset this.jsLibLoaded=true>
<cfset this.headline="h1"/>
<cfset this.subHead1="h2"/>
<cfset this.subHead2="h3"/>
<cfset this.subHead3="h4"/>
<cfset this.subHead4="h5"/>
<!--- Adjusted to nav to add the ability to prevent all children from being displayed --->
<cffunction name="dspNestedNavPrimary" output="false" returntype="string">
... a bunch of custom code here ...
</cffunction>
<cffunction name="dspPrimaryNav" returntype="string" access="public">
... a bunch of custom code here ...
</cffunction>
</cfcomponent></code></pre>
<p>Don’t worry about the two functions. The only really juicy bit there is the <code>extends="mura.content.contentRenderer"</code>, which is the way Mura suggests you implement your own custom <code>contentRenderer.cfc</code>. So now that that’s complete, let’s go into our site folder at <code>oursite/includes/</code> and open the contentRenderer.cfc file there. Change the code to this:</p>
<pre><code><cfcomponent extends="custom.contentRenderer">
</cfcomponent></code></pre>
<p>Now your site’s <code>contentRenderer.cfc</code> will pick up the custom methods in your <code>custom.contentRenderer</code> which will in turn pick up all of the default methods in <code>mura.content.contentRenderer</code>. Now you just need to make sure that every site’s contentRenderer extends <code>custom.contentRenderer</code> and you’re good go to.</p>
<p>One thing to watch for here is that if you use the Site Bundle feature, when you deploy the bundle to another server, if the custom.contentRenderer.cfc does not exist, you’ll get errors. So just be mindful of that, and you’re good to go.</p>
Calculate Next Billing Dateurn:uuid:31E15894-1D09-2C37-5FA0C2C457B74C2E2010-12-10Thh:12:ss-06002013-08-14Thh:08:ss-0500Daniel Short
<p>I had a need to figure out the next billing date after today, based on a known start date and billing interval. Here’s the function I came up with to make it happen.</p>
<pre><code><cffunction name="getNextBilling" access="public" output="false" returntype="date" >
<cfargument
name="StartDate"
type="date"
required="true"
hint="The date the billing started"
/>
<cfargument
name="BillingInterval"
type="numeric"
required="true"
hint="The number of units for the billing. For example,
if something is billed every 90 days, this value will be 90"
/>
<cfargument
name="IntervalUnit"
type="string"
default="d"
required="false"
hint="The date part for the billing interval. This is the
CF datepart, such as 'd', 'm', 'yyyy', etc. The default is 'd'."
/>
<cfset var TimeFromStart = DateDiff(Arguments.IntervalUnit, StartDate, Now()) />
<cfreturn DateAdd(Arguments.IntervalUnit, TimeFromStart + Arguments.BillingInterval - (TimeFromStart MOD Arguments.BillingInterval), Arguments.Startdate) />
</cffunction></code></pre>
<p>Let me know if you spot a problem with the solution, or have suggestions for improvement.</p>
Show in Finder in Eclipseurn:uuid:DBB63647-1D09-2C37-5FE6EEB58B9E064B2010-12-08Thh:12:ss-06002013-08-14Thh:08:ss-0500It's horribly annoying trying to find a file on your file system when it's buried folders deep in your project, on who knows which hard drive. In an effort to make this easier I scoured the interwebs for you, and found a solution.Daniel Short
<p>It’s horribly annoying trying to find a file on your file system when it’s buried folders deep in your project, on who knows which hard drive. In an effort to make this easier I scoured the interwebs for you, and found <a href="http://stackoverflow.com/questions/1161240/in-eclipse-reveal-current-file-in-filesystem">a solution on StackOverflow</a>.</p>
<p>Since ColdFusion Builder is Eclipsed based, this solution works for it as well. From CFBuilder, choose Run > External Tools > External Tools Configuration. Once there, right-click on Programs and choose New. Complete the dialog as shown below:</p>
<p><img id="externaltoolsconfiguration" src="http://dansshorts.com/assets/content/images//ShowInFinder.png" alt="External Tools Configuration" title="External Tools Configuration" /></p>
<ul>
<li>Location: <code>/usr/bin/open</code></li>
<li>Arguments: <code>${container_loc}</code></li>
</ul>
<p>After completing the fields, click Apply, and then Run to run it for the first time.</p>
<p>Now you can choose a file from the Project Navigator, click the Run Tools icon, and choose Show in Finder.</p>
<p><img id="runshowinfinder" src="http://dansshorts.com/assets/content/images//RunShowInFinder.png" alt="Run Show in Finder" title="Run Show in Finder" /></p>
<p>No more hunting through Finder windows for that illusive CSS file.</p>
ColdFusion 9: AJAX Controls and Techniquesurn:uuid:D735E818-1D09-2C37-5F83570B1BE0E65A2010-06-07Thh:06:ss-05002010-06-07Thh:06:ss-0500Daniel Short
<p>AJAX: The panacea for all of your Web 2.0 problems...</p>
<p>Well not really... AJAX can sometimes cause more problems than it solves. Especially if you don't have a good handle on exactly what it is you're doing with it. The AJAX frameworks available today are large and daunting, and can be extremely intimidating.</p>
<p>ColdFusion, sticking with its "make hard thing easier" mantra, has done a lot of work to make it easy to incorporate AJAX functionality into your sites. Unfortunately, this requires a little training as well :-)</p>
<p>To get you started, I'm happy to announce the release of <a href="http://www.lynda.com/home/DisplayCourse.aspx?lpk2=59951">ColdFusion 9: AJAX Controls and Techniques</a>.</p>
<p>This course will take you through all of the basics of using AJAX controls and techniques in ColdFusion 9 (is that a descriptive title or what!?)</p>
<p>After watching this course, you'll come away with the following nuggets of wisdom:</p>
<ul>
<li>Manipulating and securing container contents</liL>
<li>Debugging AJAX behaviors</liL>
<li>Building UI elements such as accordions and border layouts</liL>
<li>Using rich prompts with cfmessagebox</liL>
<li>Understanding advanced cffileupload</liL>
<li>Sorting and grouping data in grids</liL>
<li>Binding data to form fields</liL>
<li>Creating a map with markers</liL>
</ul>
<p>
I hope you enjoy the new title, and let me know if you have any questions. I'll be watching the comments :-).
</p>
ColdFusion Builder Essential Training Launchedurn:uuid:39649B58-1D09-2C37-5F2CD053067B70732010-03-22Thh:03:ss-05002010-03-22Thh:03:ss-0500Daniel Short
<p>ColdFusion Builder has finally been launched!</p>
<p>It seems like it's been forever since the original Bolt beta started, but CFBuilder is finally hitting the streets. I've been using Bolt and CFBuilder as my one and only ColdFusion IDE since the early Bolt betas, and I can tell you that I have no intention of going back to one of those "others".</p>
<p>After a few frustrations with early betas I tried going back to CFEcilpse (and even Dreamweaver at one point), but just couldn't bring myself to go without all of the fantastic component auto-completion and server integration.</p>
<p>There's lots of blog coverage of the release of ColdFusion Builder, including talk of new features, so I won't talk at length about any specific features. I do, however, want to point you to my new <a href="http://www.lynda.com/home/DisplayCourse.aspx?lpk2=60518">ColdFusion Builder Essential Training</a> title at lynda.com.</p>
<p>ColdFusion Builder Essential Training is designed to teach both new and experienced ColdFusion developers how to configure servers and services, generate data-aware components, and create custom extensions. It doesn't cover every single little in and out of ColdFusion Builder, but it will go a long way to helping you get up to speed with the new product. Topics include:</p>
<ul>
<li>Installing ColdFusion Builder</li>
<li>Customizing the ColdFusion Builder workspace</li>
<li>Managing assets within a project</li>
<li>Setting up ColdFusion servers</li>
<li>Coding with Code Assist, code coloring and syntax checking</li>
<li>Using snippets</li>
<li>Working with components and variable mappings</li>
<li>Creating ColdFusion Builder extensions</li>
</ul>
<p>I hope you enjoy the new title, and let me know if you have any questions. I'll be watching the comments :-).</p>
SQL Blocking and Client Variable Purgeurn:uuid:7F4A7E72-1D09-2C37-5F938170BC94374E2009-12-11Thh:12:ss-06002010-10-07Thh:10:ss-0500Daniel Short
We've had continual issues with our ColdFusion applications locking up on us. I've spent the last week cleaning out huge tables, creating indexes, and tuning queries, but could never seem to track down what was causing the issue. Today I caught it in the act... As the the applications locked up, I ran the following query in SSMS:
SELECT
st.text
, r.blocking_session_id
, r.session_id, r.status
, r.command
, r.cpu_time
, r.total_elapsed_time
FROM
sys.dm_exec_requests r
CROSS APPLY
sys.dm_exec_sql_text(sql_handle) AS st
This showed me what queries were getting blocked, and who was doing the blocking. It turns out that it was ColdFusion's Client Variable purging that was causing the blocking. This is the query that was running:
DELETE FROM
CDATA WHERE CDATA.cfid in
(SELECT CGLOBAL.cfid
FROM CGLOBAL
WHERE CGLOBAL.lvisit < {date} )
DELETE FROM CGLOBAL WHERE CGLOBAL.lvisit < {date}
Unfortunately, there are no lock hints anywhere on the query. With 7,500 records to delete in a table with more than 30,000,000 records, the table was getting locked for more than 2 minutes, a complete disaster for a production application dependent on client variables.
So I went to work creating a new query that will delete the client variables at a much more reasonable pace, with only as much locking as is necessary to keep things humming along smoothly. The new query looks like this:
SET NOCOUNT ON
DECLARE @cfid char(64), @rowsaffected int, @rowsdeleted int;
SET @rowsaffected = 0;
SET @rowsdeleted = 1;
WHILE @rowsdeleted > 0 AND @rowsaffected < 100
BEGIN
BEGIN TRANSACTION
SET @cfid = (
SELECT TOP 1 CGLOBAL.cfid
FROM CGLOBAL (NOLOCK)
WHERE CGLOBAL.lvisit < DATEADD(d, -30, GETDATE())
ORDER BY CGLOBAL.lvisit
)
DELETE FROM CDATA WITH (ROWLOCK) WHERE CDATA.cfid = @cfid
DELETE FROM CGLOBAL WITH (ROWLOCK) WHERE CGLOBAL.cfid = @cfid
SET @rowsdeleted = (SELECT @@ROWCOUNT);
SET @rowsaffected = @rowsaffected + 1;
COMMIT
END
PRINT CAST(@rowsaffected AS varchar) + ' client records deleted'
The query will loop through and delete one record at a time, until it hits the limit of rows affected specified. This is set up as a scheduled task in CF so that I know exactly when it will happen, and can watch for issues if there is a failure using existing global error catching.
Convert IPs to Integersurn:uuid:50CA4EA6-1D09-2C37-5FCBCAFE19984D712009-12-02Thh:12:ss-06002010-10-07Thh:10:ss-0500Daniel Short
More fun with IPs, this time converting them to integers.
<cffunction name="IPtoInt" output="false" returntype="struct"
hint="Returns a struct with two nodes<br />
Start: The starting IP address for the range specified<br />
End: The last IP address in the range
Range: Number of IP Addresses in the range"
>
<cfargument name="IPAddress" type="string" required="true" hint="" />
<cfset var LOCAL = StructNew() />
<cfset LOCAL.retVal = StructNew() />
<cfset LOCAL.retVal.range = 0 />
<cfif ListLen(Arguments.IPAddress, ".") LT 4>
<cfset LOCAL.retVal.range = 255^(4-ListLen(Arguments.IPAddress, ".")) />
<cfloop from="1" to="#4-ListLen(Arguments.IPAddress, ".")#" index="LOCAL.i">
<cfset Arguments.IPAddress &= ".0" />
</cfloop>
</cfif>
<cfset LOCAL.Octets = ListToArray(Arguments.IPAddress, ".") />
<cfloop array="#LOCAL.Octets#" index="LOCAL.octet">
<cfif LOCAL.octet LT 0 OR LOCAL.octet GT 255>
<cfthrow
type="exception"
message="Invalid Octet"
detail="The octet '#LOCAL.octet#' is outside acceptable range. Octets must between 0 and 255." />
</cfif>
</cfloop>
<cfif LOCAL.Octets[1] LT 128>
<cfset LOCAL.base = LOCAL.Octets[1] * 16777216 />
<cfelse>
<cfset LOCAL.base = -(256 - LOCAL.Octets[1]) * 16777216 />
</cfif>
<cfset LOCAL.retVal.Start = LOCAL.base + (LOCAL.Octets[2] * 65536) + (LOCAL.Octets[3] * 256) + (LOCAL.Octets[4]) />
<cfset LOCAL.retVal.End = LOCAL.retVal.Start + LOCAL.retVal.Range />
<cfreturn LOCAL.retVal />
</cffunction>
Convert IPs to Binaryurn:uuid:4FB9623E-1D09-2C37-5F011B80567467D72009-12-02Thh:12:ss-06002010-10-07Thh:10:ss-0500Daniel Short
I'm working on some SQL to search for data based on IPs and IP Ranges. Doing this with character data in the database is horrendous. When searching through millions of records using JOINs with LIKE comparisons, the performance is completely unacceptable. So I'm working on converting the IP addresses to Binary format to do some (hopefully) faster searching.
I have all of the SQL code to do this, which I'll post a little later with some performance benchmarks, but first some ColdFusion code to deal with display and conversion of IP addresses to and from binary. If you use the code, please let me know if it works out for you, and look for a further post on making use of this in SQL Server.
So, without further ado, here's the function:
<cffunction name="ConvertIP"
output="false"
returntype="any"
hint="Converts an IP to either Binary or dotted decimal notation
based on the format of the IPAddress argument">
<cfargument
name="IPAddress"
type="any"
required="true"
hint="The IP Address to be converted.
If the supplied value is binary, it will be converted to dotted decimal.
If the supplied value is dotted decimal, it will be conerted to binary." />
<cfset var LOCAL = StructNew() />
<cfset LOCAL.retVal = "" />
<cfif IsBinary(Arguments.IPAddress)>
<!--- Convert to dotted decimal --->
<cftry>
<cfset LOCAL.hexIP = BinaryEncode(Arguments.IPAddress, "hex") />
<cfset LOCAL.retVal =
InputBaseN(Mid(LOCAL.hexIP, 1, 2), 16) & "."
& InputBaseN(Mid(LOCAL.hexIP, 3, 2), 16) & "."
& InputBaseN(Mid(LOCAL.hexIP, 5, 2), 16) & "."
& InputBaseN(Mid(LOCAL.hexIP, 7, 2), 16)
/ >
<cfcatch>
<cfthrow
type="exception"
message="Invalid Binary IP format"
detail="The binary data supplied could not be converted to an IP.
Please verify that the data is formatted correctly." />
</cfcatch>
</cftry>
<cfelse>
<!--- It must be dotted decimal, convert to binary --->
<cfif ListLen(Arguments.IPAddress, ".") NEQ 4>
<cfthrow type="exception"
message="Invalid IP Address Format"
detail="The IP address '#Arguments.IPAddress#' is not a valid dotted decimal IP address." />
</cfif>
<cfloop list="#Arguments.IPAddress#" delimiters="." index="LOCAL.octet">
<!--- Convert to BaseN and add leading 0's to pad values --->
<cfset LOCAL.RetVal &= Right(0 & FormatBaseN(LOCAL.octet, 16), 2) />
</cfloop>
<cfset LOCAL.retVal = BinaryDecode(LOCAL.retVal, "hex") />
</cfif>
<cfreturn LOCAL.retVal />
</cffunction>
Error when Upgrading to CF9urn:uuid:2718FD13-1D09-2C37-5F2E07C4F25D0AC62009-11-24Thh:11:ss-06002009-11-24Thh:11:ss-0600Daniel Short
<p>I finished the installation of our new CF9 license with just one hiccough along the way. I installed CF9 next to CF8 so that we can move clients over to the new CF9 server one at a time and test as we go. After the file installation is finished, CF9 opens the migration wizard to allow you to bring over all of your old CF8 settings. During this process I got the a monstrous cfdump with the following error:</p>
<blockquote>Server Monitoring And API is not available in this edition of
ColdFusion server.</blockquote>
<p>A quick Google search didn't return any relevant results, but a quick email to the CF team got a me a link to a <a href="http://kb2.adobe.com/cps/527/cpsid_52797.html">Knowledge Base article</a> with the answer. I replaced the two CF8 migration templates with the ones provided from teh article, went back to the CFAdmin, and everything finished without a hitch.</p>
IE8, ColdFusion, and Color Profilesurn:uuid:EAF10432-1D09-2C37-5F5B9EFA67E081BB2009-11-12Thh:11:ss-06002009-11-12Thh:11:ss-0600<p>We do a massive amount of image processing on LandsofAmerica.com. Our
image processing scripts take uploaded photos from realtors and create
multiple versions at different sizes for use throughout our
applications. This has been working without a hitch for ages.
Unfortunately, IE8 was released...</p>Daniel Short
<p>We do a massive amount of image processing on LandsofAmerica.com. Our
image processing scripts take uploaded photos from realtors and create
multiple versions at different sizes for use throughout our
applications. This has been working without a hitch for ages.
Unfortunately, IE8 was released...</p>
<p>We did a lot of testing with IE8 before it was released to make sure everything on our site was working well. Unfortunately, after the official release of IE8, and the subsequent push of the browser out to the general populace, we started to get odd reports from users that the colors of the photos they were uploading wasn't right. Take a look for yourself:</p>
<div style="text-align:center;"><img src="/assets/content/images//badcolor-horse.png" border="0" alt="badcolor-horse.png" width="400" height="327" /></div>
<p>Something was definitely not right. We weren't seeing this with every image, and the problem didn't exist in any other browser. And while the horse looked pretty bad, this photo really blew me away:</p>
<div style="text-align:center;"><img src="/assets/content/images//badcolor-house.png" border="0" alt="badcolor-house.png" width="400" height="322" /></div>
<p>I started searching <a href="http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&hs=g5b&q=ie8+cmyk+color+profile+jpg+&aq=f&oq=&aqi=">Google for the cause of the problem</a>, and found that IE8 doesn't deal well with jpg images that contain CMYK color profiles. Unfortunately I couldn't find anything specific to the image profile issue and ColdFusion. I found lots of suggestions to use third-party components to handle image resizing instead of built-in ColdFusion functionality, but that's just not how I roll. So back to Google.</p>
<p><a href="http://www.dwmommy.com">Angela</a> found a blog post by <a href="http://david.sirr.com.au/post.cfm/errors-with-cfimage-and-cf8-image-functions">David Sirr</a> that discussed saving an image out as a PNG before doing any processing to get rid of potential corrupt image data (like funky "colour profiles") that could cause CF to hang when resizing an image. The basic premise is that you save the image to disk as a PNG (which discards all color profile data), immediately read it back in, do your editing, and then save it back to disk as a JPG when you're done (after cleaning up your PNG mess of course).</p>
<p>After adding three lines to my image processing script:</p>
<ol>
<li>Save to disk as PNG</li>
<li>Read back into memory</li>
<li>Delete PNG</li>
</ol>
<p>After reprocessing the images, our crazy alien world images were back to normal.</p>
ColdFusion Continues to Impressurn:uuid:35B27140-1D09-2C37-5F9B2C1A5EBA5CBD2009-10-08Thh:10:ss-05002009-10-08Thh:10:ss-0500Daniel Short
<p>Mark Driver from Gartner continues to be impressed with ColdFusion:</p>
<blockquote>
Here's the bottom line: no other web development toolset available today gives you an equal balance of flexibilility, scalability and out-of-the-box RAD experience for dynamic web applications than ColdFusion. There are plenty that do a better job one of these areas; there are few that do a slightly better job in two out of three; but there are none that match CF in all three areas.<br /></blockquote>
<p>Read the full article: <a href="http://blogs.gartner.com/mark_driver/2009/10/06/i-continue-to-be-impressed-with-coldfusion/">I Continue To Be Impressed With ColdFusion</a></p>
New Training - CF9 New Featuresurn:uuid:3588D90F-1D09-2C37-5FB2BD170131C4542009-10-08Thh:10:ss-05002009-10-08Thh:10:ss-0500Daniel Short
<p>I posted a <em>very</em> short note the other day when my <a href="http://www.lynda.com/home/DisplayCourse.aspx?lpk2=56299">ColdFusion 9 New Features</a> title was released, but I figured I should post a more verbose description of the title.</p>
<p>In "ColdFusion 9 New Features" I go through all of the new whiz-bang features in ColdFusion 9. I cover everything from the new AIR-Based Server Manager, to working with ORM and the new Office integration features.</p>
<p>It's nearly 3 hours of ColdFusion 9 New Feature goodness :). You can watch four videos for free! Let me know how you like it.</p>