ColdFusion Muse

Class Compiling Fun with ColdFusion

ColdFusion is Java - most people know this in the abstract sense. In sales meetings with the non-initiated I speak about ColdFusion as a layer of Java Services like mail, networking, jdbc, and compiling coupled with a language and syntax that offers faster development and better maintenance. I keep the conversation firmly rooted in Java because in reality this description is spot on. With the advent of ColdFusion 10 my case will be bolstered by TomCat as well - making it even easier to sell (and frankly it's not very hard if you know what you are doing).

Since it is Java you probably already know that ColdFusion takes your CFML code and compiles it down into Java Classes. In the days of CF 6 (back when I had more hair) you could use a command line to pre-compile CFML and even save off the .JAVA files. I'm not sure if you can still do that but it was a neat trick. Every time you run a cfm or cfc file ColdFusion checks (assuming trusted cache is off) to see if the file has changed and recompiles it if needed. You can see this happening with a little effort. The easiest way is to go to the /cfclasses folder for the instance you are using and delete all the class files that are there. Then run a CF page. You should see class files show up for every page and each function within the page.

Knowing (or not knowing) how things really work is very important to a high skill set developer. It amazes me to no end when developers profess they are "uninterested" in certain things regarding the technology they work with. I can't imagine Tony Stewart being uninterested in the bore size of his cylinders or the torque of 4rth gear or whatever. I'm sure Tiger Woods has more than a passing knowledge of how golf balls and clubs are made and customized. Indeed the more broad your knowledge and the more eclectic your skill set the more likely it is that you are an effective troubleshooter. The Muse (for example) has more than a little networking, hardware and server config experience. Often this is the difference between many hours of fruitless searching and a fast "Aha!" moment. With that in mind I'd like to share a little tidbit I picked up along the way (on StackOverflow from ColdFusion/Flex developer Sean Coyne of n42designs.com) having to do with compiling. It started with an error I have seen many times... "Routines cannot be declared more than once". I'm sharing this because I thought the work around was unique and I had not seen it before.

[More]

Web Sockets - Going Where No Muse Has Gone Before

You might wonder where I've been holed up for more than a month. Never fear - I'm still slogging away. My current project is a dashboard for CF Webtools that tracks all of our consulting activity. CF Webtools runs a custom tracking and management system as a core component of our business. This system has many cool features that have evolved over the years for tracking hours, performance, tasks, groups of tasks, assignments, productivity, estimates, deadlines etc. Myself and my VP, Jason Herbolsheimer (a brilliant programmer and manager who you would all know and love if he would ever blog), have spent thousands of hours on it to make it fit our business model of transparency, measurable productivity and cash positive block hours.

The reports and features it contains are useful, but a bit of a hodgepodge. Meanwhile, over time my role has changed considerably. Other than troubleshooting, mentoring and experimentation I'm not involved in day to day tasks directly with our clients any more. But I still monitor our overall productivity closely. Indeed, now that I'm a step back from the work I have a much better sense of what we are accomplishing and where our weak spots are. In the past I have used cfcharts called up on internal pages to show hours and individual developer performance but 3 things had changed.

  1. We now have many more developers to track (29 at last count).
  2. With 3000+ consulting hours per month the system receives a constant stream of updates, notes etc.
  3. I have a fancy new set up with 3x27 inch monitors plus a 46 inch wall mounted monitor that looked lonely and I wanted some fancy-pants dashboard to display
Ok, that last reason is simple hubris but still, it was good enough to boot me down the path. But I had some decisions to make.

[More]

Fun and Games With Googlebot

When planning for scalability one of the things that is sometimes left out is the impact of indexing bots on your site. If you have a news or ecommerce site that is constantly changing, you definitely want bots to be indexing your site. How else are the latest and greatest products or stories going to show up in organic searches after all? But you also want bots to be well behaved. It would great if you could greet the bots at the door and say "Hey... it's 2:00am, not much going on so index to your heart's content." Or, "Whoa there fella - do you have a reservation? This is Cyber Monday and I'm afraid all our seats are full for paying customers. Can you come back in 12 hours?" But that sort of smart interaction is sadly not in the cards. Some bots have defined rules, some do not. Some honor things you put in the robots.txt file others do not. So here are some tips that might save you some time.

[More]

Compiling Java With ColdFusion - Development Tip

One of the things that separate advanced developers from intermediate (at least around here) is the use of Java. Most advanced CF developers know that if ColdFusion doesn't provide precisely the functionality you are looking for you can usually find something in Java that will do the job. Now I am not talking about petulant PHP or Java developers who are being "forced" to write in ColdFusion. Such developers tend to write rather awful code that jumps through hoops in order to make ColdFusion do something the PHP way or the Java way. These folks never figure out how to take advantage of ColdFusion strengths and they are often left with code that must be refactored. Still, ColdFusion and Java are blood brothers. It's axiomatic that if CF can't do what you want, Java can usually come to the rescue. In this post we will discuss a method to treat your Java development just like your ColdFusion development - compiling it automatically at at application refresh for easy development. But first, let's talk about why working with Java can be a bit tricky for ColdFusion folks.

[More]

ASK-A-Muse: Checking for Site Availability

Muse Reader James Asks:
I have the following situation. I need to run a .cfm page that has a redirect in it to another server that serves Joomla pages. I need to find a way to test and see if that server is down or not serving pages. If it is down or not serving pages, I want to stop the redirect to that server and send the user to a page on my server. Any suggestions?

This is fairly easily accomplished using CFHTTP. When the page loads you can hit your Joomla server with a CFHTTP call and a timeout value. You could, for example, use code like this:

[More]

CF Objective Presentation Resource List

I went to cf.objective in Minneapolis last week. I was really impressed by the breadth and depth of knowledge presented by the conference. If you are looking for a conference without fluff and marketing - pure education - this is it. Virtually every seminar was in depth and included tons of resources and information. However, when I went to find the "resource" page on the cf.objective web site I was a little disappointed there was no resource portal or page. You have to "click through" to the seminar descriptions on the sessions to get to any of them. So I created this post to help myself and my staff (and others like me) who want a single page to access those presentations and resources provided by e the excellent presenters. When I dove into this I found that only about 40-50 percent of the presenters actually had their presentations online - at least from the links on the "sessions" page. So if you presented and you want a link on my resource page send me your link and I'll make sure and include it. I don't want to leave anyone out - the more the merrier. Here are the links:

[More]

Local Function Scope in ColdFusion 8

I was frustrated yesterday by the inability to get at the "local function" scope in ColdFusion 8. In ColdFusion 9 each function has a scope called "local" that functions like the various other scopes in ColdFusion. You can loop through its keys and do things with its properties. In ColdFusion 7 and 8 a great many developers actually created a pseudo local scope by doing something like "CFSET var local = structNew()" and then appending all the needed vars to this structure. In CF 9 the "local" scope was already set up for you so if you did "CFSET var x = 10" you had a var called "local.x" to work with as a member of the local object.

In the ColdFusion 8 code I was working with yesterday I had a rather long and involved function that I was trying to modify. I needed to loop through the "local" scope for one reason or another and the there was not "pseudo" local scope created. I did not want to go back and re-engineer the entire function. I was just reviewing and prototyping and there were around 25 local vars declared. So I asked the question to my list - how do I get at that local function scope without refactoring the whole function?

ColdFusion Guru Jared Rypka-Hauer came up with this undocumented solution.

<cfset var localScope = getPageContext().getActiveFunctionLocalScope()>

Sure enough, this code creates an object with all the local scope vars in it. There are a couple of caveats.

  • The Arguments structure is a part of the local scope (stands to reason right?)
  • This object (as written above) will also belong to the local scope. If you take out the "var" you've added it to the component scope.
  • Since ColdFusion 9 has created a local scope for you, this function and approach will break on a CF 9 server. so if you use it make sure you make a note that you need to modify this bit of code if you move to ColdFusion 9.

Finally, here's a little test function you can use to demonstrate to yourself how this works.

<Cffunction name="checkVarScope">
    
    <cfscript>
        var thisvar = 10;
        var thatvar = 12;
        var theOtherthing = 'Sister Sally';
        localScope = getPageContext().getActiveFunctionLocalScope();
    
</cfscript>
    
    <Cfdump var="#localScope#">

</Cffunction>

<Cfset checkVarScope()>

Here's that function in action - Local Scope.

Bamboozled by Pound Sign Decisions

If you want to greatly vex the Muse and his merry band of developers, all you have to do is send them sample code with a liberal sprinkling of superfluous pound signs and cfoutputs. ColdFusion is a very forgiving language, so you are free to do all sorts of nails-on-the-chalkboard things that make me cringe - and you will get away with it too. I began thinking about this topic because I'm privileged in my current work to review code created by others. This is double edged sword of course. It's easy to sit back and be cheeky about someone else's approach when you are in the "expert" seat. Still, I have recently reviewed code from more than 10 different developers. I've come to the conclusion that many (perhaps most) sort of guess at when to use pound signs. Once they figure out the approaches that work they stick with that.

The result is that pound signs are like Tribbles on the star trek enterprise. They are fairly innocuous but they annoying show up everywhere. So... having never seen a definitive post on the topic I thought I would jump in and put my stamp on when to use and when not to use pound signs. That's right; the Muse is not making room for other opinions this time. I'm going to lay down the law! So put your seat belts on 'cause it's going to be a bumpy ride.

[More]

The Muse and the Mac

I bought a new mac yesterday and I'm diving in trying to figure things out. The Muse knows his way around every flavor of Windows going all the way back to Windows 95 and up to every version of the server product. I cut my teeth in IT as an MS network engineer. But I've seen and fiddled with Macs before. I have added hardware (SCSI drives, controllers, RAM etc.), configured print drivers, and connected to shares on the network - all in the way of support for some of my design buddies like Erin Osterberg (a beautiful and wonderful video editor working for my good friend Rob Helling at Sonburst Communications).

But I've never actually been a Mac user. Mostly I try to stick to what works and having a modest aptitude for PC's and servers I found my niche there. It's also hard to stomach the price. It seems with the Mac you are paying twice as much for the same hardware that is in a PC... except you get that thar fancy brushed aluminum casing and a shiny mouse and brushed aluminum keyboard that looks to be made for a child.

Still, I have a need to work with some I-phone apps, so I need a Mac to run Xcode. I bought an Imac with a giant screen, set that bad boy up, rubbed my hands together and started in.



From this point forward I suspect that some of my readers will likely treat me with a rueful chuckle and some ribbing. It may be painfully obvious in the next few paragraphs how clueless I am. Anyway - here goes. Mac's reputation for being easy to use is well earned. I did not have any trouble getting my network configured and figuring out all of the personal preferences. I managed to install Firefox (and firebug), chrome and eclipse. I found the "software updates" and ran them, nicely updating a good many things on my machine. I managed to register the machine in active directory and add my domain permissions to my keychain. I even figured out how to remove all the foofy stuff I'll never use from the dock (Iphoto, Itunes, Imovie, Ichat, Ical, IstartEverythingWithI). So far so good.

Install How Exactly?

So my first "issue" is with something weird happening with installs. I installed FireFox then dragged it to the applications folder and (I think) to the dock. But on my desktop there is an item that says FireFox with an icon like a drive. There's another one that says "chrome" after that install. As far as I can see I have Chrome and FireFox in the dock. When I try to delete them Mac asks me if I wish to "eject" them. Guru Toby Tremane tells me that Mac files are downloaded as ".dmg" files - disk image files. How they got on the desktop I'll never know.

Network Follies

The muse is all about work at the office, so my next task was network resources. I was feeling good about it too. I managed to get connected to my network printer ok and I've mapped server shares before on a Mac. I have about 10 or 12 shares to mount representing various projects, shared doc storage and servers that I keep track of and visit from time to time. This turned out to be an exercise in frustration. As I see it at this point (and this may change when I find out the myriad of things I don't yet know) Mac's don't really like to play nice as windows network clients. For one thing there's no drive letter.

I knew this and expected it of course, but what I did NOT expect was the complete inability to go to the file explorer, enter a UNC path and see the share content. Surely there is something on a Mac that allows me to simply browse UNC paths ad hoc without the necessity of going through the whole "connect to a server" dance. And please, if you are going to clue me in, don't forget to tell me the shortcut keys. I go hours without touching the mouse on a PC, but the Mac seems to want me to "drag" things around to make use of them.

Once I did get a drive "mapped" (sort of) using the "connect to a network server" widget, I could only see it in the "finder" under "Devices" (not "drives" or "shares" or "network resources" but "devices"?). Furthermore I could not seem to rename the "device" once I had established the linkage. This was a problem to say the least because I had shares of the same name. For example, I mapped to ServerA with a UNC of "\\serverA\webs" and ServerB with a UNC of "\\serverb\webs". In my "devices" I now saw 2 devices both of which were named "webs". There was no way to simply rename them so I could tell them apart either. I did find I could make a sym link (an alias) to these drive mappings and rename that link. I did that on the desktop and that got me a little further.

Now, I went to open some projects (in eclipse) at these locations and I had a terrible time finding them from the browse application. Some command line searching (thank god the Linux command line is still operable) and it turns out these mapped drives are actually linked to the "volumes" folder. Well of course they are – Linux under the hood remember Mark!!

Remember my "webs" example? Closer examination showed that I had a /volumes/webs folder (mapped to serverA) and a /volumes/webs-1 folder (mapped to serverB). But in the chooser I had 2 "devices" both of which simply said "webs". And here's the kicker - clicking on either one of the devices opened only /volumes/webs-1. In other words, the short cuts in chooser were crossed up and pointed to the same share. If I navigated to the volumes folder on my own and clicked on one or the other I could get the content I was looking for, but neither the chooser nor the aliases on the desktop seemed capable of getting me to both locations.

First Take

I'm impressed with the speed and the aesthetics of the system. I suspect it will take me a week or two to really feel comfortable. Next I have to install the IOS SDK for Iphone development, Skype, Photoshop, Parallels and a few other widgets to make it more usable. The screen is also impressive. Chrome and FF both work quite well. Eclipse seems to load and run adequately. I am also seeing why some people (like super genius and senior CF Webtools ColdFusion and Java developer Guy Rish) prefer a really giant screen to several smaller ones. I have 3 21 inch monitors and I thought that was pretty grand - but that 27 inch monitor really makes a difference with Eclipse. I can get code, debugging, log tailing and file explorer on the screen without sacrificing a clear view of any of them.

Final Caution

As you can tell from this post, I'm not afraid to put myself out there. I'm trying something new and I want to share, both personally and professionally, my take from the experience. I welcome comments to my blog as all my readers know. Indeed, some of the best coldfusionmuse.com content is often found in the comments. So with that caveat, I want to say that this is not the time for the old Mac vs. Windows debate. If you wish to flame and draw out that argument I can assure you that your comments won't last here. Please keep the discourse civil. If you have tips about how to help an old windows hand get the hang of a Mac, that would be splendid. If you want to address any of my specific points in this post - have at it. But if you only wish to jump in and start a holy war, please refrain. I'm sure there is plenty for us to learn without resorting to useless and trivial arguments. Ok... now that wasn't so bad was it Muse readers? Don't worry - the Novocain wears off in about 90 minutes :)

UUID Magic With Java - When Speed is Critical

Note, this post is compiled from information foraged and provided generously by the inestimable Brian Meloche who's ColdFusion skills are (quite obviously) legendary. The Muse gives praise where praise is due - and with a nice dose of hyperbole to boot.

Many folks use UUID's for various reason. CF has a nice function built in that handles UUID creation - createUUID(). Try it out - use <cfoutput>#createUUID()#</cfoutput>. You should see a funky 36 character string that looks like this - 7C286425-CA3D-1B10-16A3CCD259C21FEE. If you are new to ColdFusion or programming in general you might not realize what's special about the UUID. It is guaranteed to be unique - at least within reason. There is a statistical probability that a duplicate is possible, but your chance of finding one is about the same as being kissed by Ann Paquin or being intellectually stimulated by the show "Jersey Shore". If you want to know more about the uniqueness of UUID's check out this interesting (or mind numbing - depending on your perspective) article on Wikipedia.

Just how would you use a UUID? There are a myriad of ways. You could store it as a cookie to identify a "unique" visitor. You could use it to tie into your custom "roll your own" session management. You could use it as part of a seed for encryption. But probably the way most folks use it is as a primary key to the DB. Now I know that most RDBMS systems include a built in UUID function. If you are planning on programming for one DB (and there are often very good reasons to do so) then I recommend using the built in function. It's typically faster to have your DB Server create something like a UUID than passing a 36 character string to it via the JDBC driver. However, if you wish your code to be portable then it's likely you will be creating your own UUIDs using ColdFusion's built in functionality.

Slight Problem

If you are using a version of CF prior to version 9 then ColdFusion has a particular way of generate UUIDs that is tied to the clock and MAC address. It is capable of generating about 100 per second. There are times when that number might become a bottleneck on a high traffic site. For example, if you are at the peak of your traffic with 700 or 800 concurrent connections and suddenly an aggressive bot starts crawling your site. ColdFusion may not be able to quite keep up with that number of generated UUIDs (assuming your Bots are generating UUIDs through you code somehow – logging, sessions or whatever).

Fortunately there is a "JAVA" way to do UUIDs that is able to get around this issue. Actually (quoting Brian) there are 5 "classes" of UUID in the java.util package. CF Apparently uses a slower one of the 5 (presumably more compatible with disparate environments or whatever). The following Java code uses a different one of those classes. The code is pretty easy to figure out. In most cases you could simply drop this code in to replace your createUUID() code:

<cfset uuid = createobject("java", "java.util.UUID") />
<cfset newUUID = uCase(removeChars(uuid.randomUUID().toString(), 24, 1)) />


Another Brian, Brian Ghidinelli, published this post where he tests the speed of createUUID() against the Java code above and finds a nearly thousand times increase in speed using the Java UUID code.

Meanwhile Brian Meloche wanted to verify that ColdFusion 9 improves the performance of the original CreateUUID() so he ran the following test on both platforms:

Old:

<cfset timeIs = getTickCount()>
<cfloop from="1" to="1000" index="i">
    <cfset uuid = createUUID() />
</cfloop>
<cfset timeIs = getTickCount() - timeIs>

New:

<cfset timeIs = getTickCount()>
<cfloop from="1" to="1000" index="i">
    <cfset uuid = createobject("java", "java.util.UUID") />
    <cfset new = uCase(removeChars(uuid.randomUUID().toString(), 24, 1)) />
</cfloop>
<cfset timeIs = getTickCount() - timeIs>


What did he find? While ColdFusion 8 benefited tremendously from the Java version with a 200 to 1000 times improvement, ColdFusion 9 saw only a modest 10 times improvement. From this test I think we could reasonably conclude that using ColdFusion 9 you are not likely to run into any problems with UUID bottlenecks regardless of whether you use createUUID() or the Java version of the code.

Linux ColdFusion Instance Taking too Long to Restart

Here's an issue I was involved in only on the very fringes. ColdFusion restarts of specific instances on a multi-install Linux server were taking forever due to session replication, but we could not see that replication was actually turned "on". There was no cluster and no admin setting indicating replication was on, but the log files definitely indicated sessions were being restored after a restart. The fix actually comes from ColdFusion Guru Brian Ghidinelli.

Brian's post is quite thorough so I won't indulge in my usually wordy explanations. Suffice it to say that when you create a new instance the jrun-web.xml file needs to be copied to your new instance specific /web-inf directory and configured with session replication off. If it's not there, copy it from the /cfusion instance. Apparently on Linux this file is not appropriately copied into individual instances that you create, so CF reverts to the default behavior for all settings in that file (meaning replication is on but you can't see how). See Brian's post for very specific instructions.

Forms, Datasets, Looping and Updating - a Simple Example

Recently my good friend and colleague Mike Klostermeyer - who everyone would recognize as a brilliant programmer and guru if he would just learn to blog - suggested that I include some simpler posts among my obscure troubleshooting play-by-plays. Here's one that most CF programmers have had to overcome at some point. Now before we go on I have to point out that there are 4 or 5 ways to do this - not counting things like Hibernate and the "black box" stuff that ships with many frameworks. What I'm illustrating here is the capabilities of the language. Moreover, if you have to support any legacy code (as 95% of us do) then you don't always have other options. You have to find a solution that works in context. With that in mind let's proceed.

[More]

Another SQLi Attack: Urchin.js

I spent yesterday cleaning and inoculating another server infected with SQL Injection. Unless you have been living in a cave you know that SQL injection (SQLi) is the most common vulnerability of web based application. This is due to 2 factors - 1) almost all databases use numeric fields and B) web applications by nature pass user input into queries. Of course I could throw in there that web developers are often lax about inoculating their code. There is also the problem of legacy code - code that has been around since the dark ages of the late 90's. Of course SQLi has been around that long as well, but it is surprising how much legacy code chugs along for a decade or more with no problem in spite of the vulnerability.

Anyway, here's the skinny on the latest attack I found. It uses our old friend "Cast" in conjunction with the char() function of MS SQL. Note, this is not a new attack on the web - it's only new to me in that I've never battled this particular attack before.

[More]

Cfobjectcache Docs Wrong? Inconceivable!

In this post I'm going to claim that part of the official documentation is wrong. Whenever I do this sort of thing I always think of the movie "The Princess Bride" when Enigo says "You kep using that word... I do na think it means what you think it means". Be that as it may, I think the docs in this case are ambiguous at best and at worse downright misleading. There's an obscure little tag called cfobjectcache that's available in ColdFusion server. Although it was a part of ColdFusion 5, I first became aware of this tag in Cf 8. You can find Adobe's documentation for the tag here. If you read the documentation (always a good idea - the muse is great but he doesn't write about everything) you may get the wrong idea about this tag. At the top of the documentation it says (and I quote), "Description: Flushes query cache". Well that's straightforward enough isn't it? This tag is designed to flush the cache of queries on the server. It's easy to use:

<cfobjectcache action="clear"/>
...poof - your query cache is back to square one. Well not so fast my friend...

[More]

Choices for Client Vars: Registry Bad, Datasource Good

Client Variables and the Registry

Ask any experienced ColdFusion troubleshooter and he will tell you the same thing, "Don't store client variables in the registry." In fact, when examining a sick server one this is one of the first items I look at. If the customer says "It seems like the server stops about every hour" it's a safe bet that the default storage is set to Registry and the default purge interval has been left alone at 1 hour and 7 minutes (which is kind of an odd interval - probably some Adobe employee's anniversary in binary).

In many cases this is a "hidden" problem waiting to burst onto the scenes and bite some poor site owner in his nether regions. The owner launches his or her site and begins to gather traffic with the default settings for client variables. By default ColdFusion stores 90 days worth of client variables in the Registry - so the site can actually perform well for a few months. But then, out of no where, the server starts to drag and even stop every hour or so. Under the hood the purge operation is starting to find client vars that are 90 days old or more and it is taking quite a long time to delete them. The OS sees the registry keys being deleted and (sometimes) attempts to shrink the registry size. This affects a sort of "locking" on the registry where new keys are not being written - meaning requests are queuing and the server is slowing to a crawl. Now you might think that fixing this is as easy as switching from the registry to a datasource or cookie storage as the default, but there are some nuances to this fix that bear mentioning.

[More]

More Entries




Blog provided and hosted by CF Webtools. Blog Sofware by Ray Camden.