For several and various reasons, I am moving all of my professional content over to a new site: TerrenceRyan.com. If you're subscribing to this site for web development, ColdFusion or other web development matters, please point your RSS readers and aggregators to TerrenceRyan.com.
Basically, I was looking to do a redesign and purge a bunch of outdated content. I also wanted to divorce some of my personal content from my professional image. I've also gotten a few complaints from my friends that they have ceased to understand any of what I'm talking about. I've had TerrenceRyan.com for awhile, and figured it was time to put it to use.
Part of the move was also a switch to Mango Blog from MovableType. I have to say AsFusion have done a great job with it - it's so easy to configure and customize.
Anyway, switch over, and for those that like my personal nonsense there should be more of it coming. For those of you looking for CF information more is coming on that front too.
November 6, 2008 Posted by Terrence Ryan at 3:05 PM
I ran into a problem with our standard configuration for web servers, and couldn't find the real solution documented anywhere, so here it does.
We run our ColdFusion servers on dual node Windows Network Load Balancing (NLB) servers running in IGMP multicast mode. We run it on machines with two network cards. The cluster address is on one NIC and the nodes answer on another. It's the configuration we've come to like after years of working with NLB and port flooding and other anomalies.
I'm installing a new production NLB cluster for Knowledge@Wharton. To future proof it, and avoid upgrades down the road, I'm going with ColdFusion 8 64 bit on Windows 2008 64 bit. I ran through the configuration steps that I always take setting up an NLB cluster, and it worked sort of. See the cluster address answered if you called it from another host on the subnet that the cluster was installed on. However, if you were off subnet it didn't answer. This is suboptimal for a web server.
I worked with our networking team, and they figured out (from this post: http://social.technet.microsoft.com/Forums/en-US/winserverClustering/thread/0afdb0fc-2adf-4864-b164-87e24451f875/ ) that if you added a gateway to the cluster NIC, it would work. This is counter to the way NLB has worked before, and generally not best practice. So we opened a support case with Microsoft. After a few tries, I finally got an engineer that was an expert on NLB in 2008, he had the exact cause and solution for this problem: by default IP Forwarding is not enable in Windows 2008. This is the feature of Windows networking that, in the context of NLB, allows responses to requests sent to one NIC to be routed out the other. It's fixed by using one specific command line option.
(Make sure you are using a command prompt with administrative privlidges)
netsh interface ipv4 set int "[name of the NIC]" forwarding=enabled
That's it.
October 29, 2008 Posted by Terrence Ryan at 1:19 PM
A few weeks ago, I went searching for a provider for hosted SVN, I tried a few different services, and in the end went with Unfuddle.com. Over the course of the past few weeks, my team has grown dependent on Unfuddle as part of our work flow, and I have grown to absolutely love the service.
One of the only caveats is that we aren't used to relying on outside services for that sort of mission critical part of our environment. So the thought of our information out a server that we didn't control started disaster recovery talk, and one of the important things to make sure we had was a backup of our content from Unfuddle. Now, they were one step ahead of us, they include the ability to ask for backups, which include svn dumps, as part of the service. They go one step further, and actually have this as part of their API.
Being the automator that I am, I automated requesting a backup, checking to see if it was finished, and downloading it, so that we now have fresh copies of our data every week. In the course of doing that I created an Unfuddle.cfc that provided hooks into their API. I decided to share it, and the backup application on RIAForge for a few reasons:
I know a few CF'ers are using Unfuddle.
I figured some non-CF'ers might want to functionality enough to give CF a try
It's not a complete implementation yet. I've gotten done as much I need for the backup application. I'm then starting to fill out the features. If there is a feature you would like from the Unfuddle API, please let me know. In any case, check out Unfuddlecfc.
Another thing I have to say is that the Unfuddle guys did an awesome job writing this API (at least as far as I've coded). There are just all of these little details that make it very easy to use. It's really easy to pass queries, and options to the various REST commands, because it takes those options a few different ways. The other thing they did was make sure that responses are very uniform, so it was really easy to write rules for processing their results. Between the API and the app itself, the crew at Unfuddle is a real credit to Ruby on Rails.
September 30, 2008 Posted by Terrence Ryan at 4:58 PM
I'm pleased to announce that Squidhead is getting some more chefs. I'm pleased to announce that Nathan Mische and Dave Konopka are joining the effort. I'm excited about both additions. Dave was working with me when I first wrote Squidhead and has already contributed some code. Nathan is, of course, the lead developer on ColdFire.
We're still working out what's coming down the pike, but improvements will include:
A more organized and useful API to the database introspection piece.
A better template system
A configuration creator and editor
It's all towards making Squidhead more useful and extendable. Expect new releases soon.
September 25, 2008 Posted by Terrence Ryan at 11:01 PM
I'm pleased to report that the Knowledge@Wharton team launched a pre-release site for the upcoming Knowledge@Wharton High School. If you are, or know any high school students send them along. We're launching in February 2009, and as part of that, are holding an essay contest with prizes. I don't think we've spelled out what those prizes are, but from discussions I've heard, they're pretty awesome.
It's powered by ColdFusion 8, and Flash Video. I worked on the backend details: hosting, network configuration, database CRUD. My co-worker Sanjay did the design and UI, and my boss Dave, did the Flash video setup. The time it took us to go from mockup to finished product was very short - we did this much quicker than I had done before for non-personal project. I know it isn't a huge site, but after years of working on nothing but backend systems that never get seen by the public, it was extremely satisfying to work on something that wasn't behind a corporate login.
A couple other things make me happy about this. Squidhead powered backend development, which made dealing with last minute schema changes a snap. It also used the core application framework that I've been developing for Knowledge. It was the first project we did with the new one click build process. It uses unfuddle.com, SVN commit hooks, ANT, and ColdFusion calling ANT to allow for:
Automatic publishing of SVN checked-in content to a shared development server
1 Click publishing of checked in content to a shared development server (In case automatic is too slow)
1 Click publishing of shared development space to staging
1 Click publishing of staging to production
1 Click publishing of SVN checked-in content to development to staging to production
This new model allowed for both a thoughtful develop and review process during development, and was flexible enough to allow for rapid content updates when we were rolling out production.
All in all, it was awesome to use all of the stuff I learned about over the past two years at cf.Objective to do my job.
September 25, 2008 Posted by Terrence Ryan at 11:05 AM
I received an interesting challenge today from my boss.
We recently switched from requiring people to be logged into the site to read our articles to being open, and only requiring logins to comment. Because of the previous restriction and a large amount of our audience being corporate users with cookies disabled, we have URLSessionFormat wrapping all of our internal links spread out over a few template pages, over a few of our sites. Now that we don't have to be as careful about checking logins it would be better to make sure all of our urls are cleaner (i.e. not having the session information appended to it). My boss wanted to avoid having to edit all of those files. So that challenge to me was to figure out how to override c and make sure our urls were clean.
After fiddling with getPageContext to no avail I settled on this solution:
Grab the page content in Application.cfc:onRequest()
Replace any reference to the jsessionid in the page.
It's not bad, and it doesn't add a tremendous amount of overhead to every page, and would have worked if this was imperative to do. We decided however that string processing every single request was probably not preferable to just finding and replacing all of the URLSessionFormat() references.
September 19, 2008 Posted by Terrence Ryan at 1:47 PM
The current economic crisis is catching many people flat-footed and confused:
Why did financial entities that survived the Great Depression go belly up this week?
What do the two campaigns really have to say about the economy?
What's going to happen next?
If only there was some sort of site that took that sort of economic information from academic and industry experts and distilled it to the answers that you need Wait a minute, I just happen to work for such a group
This is my round about way of telling you all that Knowledge@Wharton (My current employer) has a special section this week on the Financial Crisis, and it's powered by ColdFusion and Flash Video.
September 17, 2008 Posted by Terrence Ryan at 10:15 PM
I had a weird issue today , and I thought I'd share.
I was having trouble reproducing an issue that a client was reporting in the flow of a page that was posting back to itself. No matter what I did I couldn't get it to occur on my machine.
I then went over a dump of the cgi scope and noticed they were using Safari. I gave it a try, and BOOM, same problem.
I looked at what was happened, and it looked like the querystring of the last request was added to the querystring of where I was trying to cflocate.
So I was posting to "?method=delete_process&id=1" and cflocating to "?method=list" when I was done. Firefox tried to cflocate to "?method=list" but Safari posted to "?method=delete_process&id=1?method=list". This caused the error, as id=1 was already deleted, and even if it wasn't id=1? was invalid.
The fix was to prepend "#cgi.script_name#" before the question mark.
After a quick search, it turns out that this has come up in Forum over on Ray's site (cflocation & safari).
September 17, 2008 Posted by Terrence Ryan at 12:07 AM
Last week's issue of Knowledge@Wharton (my current employer) featured a pretty cool interview with Charles Geschke, one of the co-founders of Adobe. There's a lot of great content, from stories about Steve Jobs and the beginning of Adobe, and the story of how they dealt with a hostile takeover attempt from Quark.
One of things I found was interesting was the inclusion of an internal document that outlined Adobe's corporate values. It was a pretty interesting window into their overall philosophy, and a clear sign that as a company they are discouraged from wasting people's times in meetings.
Thanks to being quick on the old reply key I got myself on the speakers list for the ColdFusion Unconference. I'll be speaking on Wednesday Morning at 9:30.
My session is on Formal Code reviews. I've spoken on them before, so I think I'm going to add a twist to achieve the whole "unconference" vibe. I think after I give my presentation which outlines how to go about code reviews, we're going to go through that process with a piece of code. Granted it won't be a full blown application, but it should give people a chance to actually feel how it works when you're doing it the way I call right.
If anyone has anything they would like to hear or see discussed, let me know.
August 2, 2008 Posted by Terrence Ryan at 11:31 AM
So once again, I'm moving jobs. I'm still with the Wharton School. However, now I will be working for Knowledge@Wharton. I'll be working on small and medium sized projects, working on growing the backend platform, and anything else they tell me to do.
I'm pretty excited about the move. I'll be joining a great team, it gives me an opportunity to work for a former boss again, and it's a lot easier to point someone to a public site like Knowledge as an explanation of what I do.
I start Tuesday, after a visit to DC this weekend.
I ran into a difficult Unit testing problem the other day. I had trouble determining the correct test to write, and finally did so. I thought that perhaps someone else might benefit from an exploration of testing strategy.
As you might know, we create pdf's using ColdFusion for ExportReports.com. One of the new features we are adding is the ability to set the page size (legal, letter, A4 etc.) As page size is a feature, I need to test it. So I need to create a pdf file then determine what its page size is. At first I explored <cfpdf> and its ability to get at PDF metadata. No joy - it turned out that page size isn't one of the things returned in the metadata. Then I looked at <cfpdf>'s ability to get thumbnails of the pages in the pdf. I could use <cfimage> to get the information about height and width of the image files, put that was in pixels and hard to translate to inches. (I tried assuming 300dpi, it did not yield good results.) Then it dawned on me that ratio of height to width could yield helpful answers. I found the dimensions in millimeters for the various page types, created ratios from them, and compared them to the ratio of the dimensions of the thumbnails. Then I had to correct a bit for precision, and it yielded me a solution. Here's what it looked like in code:
<!--- Grab a processable view of the pdf ---> <cfpdfaction="thumbnail" source="#pdfQuery.directory#/#pdfQuery.name#" destination="#dirreports#tn" scale="100"overwrite="TRUE"/>
I found out last week, that I was accepted to speak at Max 2008 North America. I'll be talking about using ColdFusion to act as middleware for enterprise applications. That may not be clear from the title of my session: ColdFusion as Enterprise Middleware.
I'm pretty excited about the whole thing, and very grateful to the crew at Adobe, especially Adam Lehman, for giving me a shot to speak.
If anyone has any suggestions, or content they would like to hear about, feel free to drop me a line. I don't guarantee I'll do what you say, but I will definitely will listen.
Just a quick note if you are using Selenium to do your tests, and writing your own, you've probably had to write some XPath expressions. I had to write a particularly hard XPath string and got tired of trying to test my XPath expression in Selenium over and over again.
I did some quick Google searching and discovered a Firefox plug-in named XPath Checker. It works two ways:
It allows you to write an XPath expression and see what it returns.
It allows you to click on piece of a page and see an XPath expression that would find it
In the course of trying to get ready to release the code for Yet Another ColdFusion CMS, or Yacc, I was trying to test working with the CMS. In order to do that, I needed to get Selenium to work with it. It worked fine until I tried to edit content. I'm using cftextarea richtext=true to provide CMS editing capabilities. However, when I went to record the test in Selenium, it couldn't handle working with FCKeditor which provides the richtext capabilities for ColdFusion. After a few hours of trial and error, I was able to test them.
Here's how you do it:
First you have to do it via Selenium-RC, the Selenium Firefox IDE doesn't seem to be able to do it. You can launch pretty easily via ANT:
<!--Prerequsitesforselenium-->
<taskdefresource="selenium-ant.properties">
<classpath>
<pathelementlocation="${selenium.jar}"/>
</classpath>
</taskdef>
<targetname="template.test.selenium">
<echomessage="Running Selenium Tests."/>
<selenese
suite="${template.test.selenium.suite}"
browser="*pifirefox"
results="${log.dir}templateuitestresults.html"
haltOnFailure="true"
timeoutInSeconds="240"
startURL="${host.url}"
/>
</target>
Where:
${selenium.jar}
The path of the selenium-server.jar file
${template.test.selenium.suite}
The path to the selenium test suite.
${log.dir}
The path to a space where you store logs
${host.url}
The base url of the testing webserver
pifirefox
This is the proxy Injection version of Firefox launcher
Now you're launching your Selenium tests automatically in ANT, but you have to write your tests to actually interact with the FCKEditor. By default Selenium runs its tests as soon as the page loads. But in order to test the FCKEditor, you have to wait for it to exist. Here's the Selenese to do that:
Assuming that "content" is the name of your cftextarea, this is how you do it. You test for the "Coldfusion" object exists, then the "Coldfusion.RichText", then the "FCKeditorAPI" and finally the actual richtext area. Once everything exists, you have to set the HTML of the FCKeditor. There is no input element to type into, so you have to use the FCKEditor setHTML method. To do that you have to use a storeEval command, and then you wait for the typed element you added to appear.
Hopefully this saves a few hours of work for someone else at some point.
Knowledge@Wharton scored an interview with Adobe CTO Kevin Lynch. I think there's a lot of great content in the article. The article is mostly concerned with Air, but the part I liked best is where the interviewer asks the question I've been wondering about for awhile chiefly:
Knowledge@Wharton: The AIR run time is available as a free download. The AIR Software Development Kit is available for free. How does Adobe make any money from this technology?
Kevin goes on to answer, read the whole article for his exact answer, but basically it comes down to the fact that Adobe uses it's free products as a loss leader to encourage purchases of their other technologies including tooling and servers. He specifically includes ColdFusion in that.
I think this is another pointer to the fact that Adobe probably won't be open sourcing or making free ColdFusion anytime in the near future. That might change if OpenBD and Railo gain any sort of traction. But I'm betting against them, as I have said before.
Yesterday, I presented on AIR and SQLite (for HTML and JavaScript developers.) I've posted a zip file of all of the content, including the presentation up on my site if anyone wants to download it.
I also included the source for AboutTime, my approximate clock application.
I want a cfvideo tag for Centaur that is akin to the cfimage tag in terms of usage and abilities. I want to be able to crop, cut, manipulate, and codec video. I want to be able to easily make Flash Video content from our content.
I posit that video isn't what's next for web developers, it is what is.
I wanted to get that in before I hear what anything about the next version of ColdFusion.
cf.Objective repeated its performance as the awesomest conference ever
The entire steering committee out did themselves in terms of content and speakers.
Once again, the cf.Objective not only delivers great lectures from the experts, but the ability to actually interact with them.
Almost everything this year was better:
Room scheduling - I saw no ad hoc room changes due to audience size.
Power distribution - there were many outlets available in every room
Venue - I thought the rooms and facilities were just as good as last year, but the staff was much more helpful.
On the con side:
Wireless was terrible.
The food was hit or miss.
Neither of those two facts was, in any way, a real problem for me. Put another way, if I traveled back in time to tell me that the wireless services and food would suck at cf.Objective 2009, I would still go. Then I would be very mad that I wasted time travel on that.
As with last year, I find myself building a list of things that I will challenge myself to adopt over the next year, after absorbing all of the geek radiation at cf.O. Last year's list was about starting things: starting local development; starting to use ColdSpring. I think this is more about refining things I have used before, and getting the most out of them.
My cf.Objective 2009 ToDo list:
Perfect my build process
Move all of my projects over to "perfect one step builds"
Utilize Subversion correctly with tags and branches
Adopt an MVC framework
I'm leaning towards Model-Glue 3
Start using AOP in ColdSpring
Come up with a topic to speak again
I like talking about soft skills within technical areas, to that end I have a few ideas
Formal Code Reviews
Influence Techniques for Geeks
Hiring Effective Developers
Selling Professional Development to the Resistant Shop 2: Rise of the Uniformed
I might need to come up with some technical presentations,
Writing Boilerplate Code
Writing Code for Team Reuse
Gain traction on the rumor that Mark Mandel has a marsupial pouch
Collaborate more with people in the community
Contribute to someone else's open source project
Work with someone just for fun
Team up with somebody for a side project
So that's my list. I challenge everyone to coming up with their own, and posting it on their respective blogs.
It was with great sadness and dehydration with which I faced the final day at cf.Objective 2008.
Due to my state of "sadness" I didn't really start taking in new information until Joe Rinehart's talk on Model-Glue 3: Back to its Roots. Model-Glue 2 broke me of my resistance to frameworks, it made me willing to use them. Model-Glue 3 just makes me want to use Model-Glue 3. I really like seeing things being brought in from the RoR writing process. (Ask for something, a shell gets created, then modify it.) I can't wait until it's more documented and ready to go, as I can't consider myself an expert Model-Glue user.
Then I wandered into Mike Brunt's session on Clustering and Distributing ColdFusion Applications. I really wanted to hear Mike talk, because he is one of the few public voices on server administration in the community. I admit, I think my brain is full. But I can't really think it, because my brain is full. I did like the tip to use the default install of ColdFusion in multiserver as an admin node.
Despite that, I went to Jason Delmore's Building Hybrid Applications with ColdFusion and Java. I got a lot out of this session when he gave it a few years ago at MAX. It's definitely geeky stuff for people who want to know how things are running under the covers. But this type of knowledge is really great to have when you are trying to figure out what's going on when your application misbehaves. The part about String buffers was worth the entire session. If you deal with large string operations, take a longer look at this if the presentation comes out. I need to implement this stuff immediately.
Finally the closing section was a nice ending beat to the conference. It impresses me just how much passion the people in the room have to this niche of the professional world.
This is one of those things that's probably a pet peeve of mine because I use to do it myself, but I figured I would share what I was told during my performance days.
I've seen this phenomenon a bunch, a performer or presenter gets done, an audience member comes up and says something along the lines of "Great job," the complimented responds with something like:
"Oh I totally screwed up"
"No, I didn't really do anything"
"No, I thought it went awfully"
Invariably there are two things that drive this:
1. The presenter/performer is so caught up in their own self examination, that they are being hyper critical and sharing it with the complementer.
2. The presenter/performer is concerned about the appearance of humility.
Both ignore a greater truth in the interaction: Someone has said something nice to you, and you are immediately telling them they are wrong! Even if they don't directly perceive this, it can leave them with a bad taste in their mouth.
So what do you do? Say "Thank you," that's it. Leave the self examination stuff where it belongs, in your head. If you are concerned with your ego, accept and expand the compliment: "Thank you; I have to say the audience was really great, you guys asked really great questions."
It's a silly little thing, but it can have a big impact on how you are perceived.
My first presentation was my own. I thought it went really well, but I over pruned and ran a little short. I might have been talking fast too, but through the magic of twitter, I got instant feedback.
Neurotic Terrance Ryan - the ultimate manipulator! ;) from im
brandonmoser B. Arthur wrestlign a velociraptor is a great visual...awesome from twhirl
Neurotic I love Terrence's slides.. I really need better pictures for slides! from im
Neurotic Terrance Ryan's Professional Development in a Hostile Shop is really good! from im
seancorfield "patrick" and "john"... yeah, right... terrence nearly slipped up and used the real names :) from twhirl
Next I went to Peter Farrell's Using ANT : Make Your Development Life More Productive. Peter hit the standard stuff, but he also hit on some other ideas, like using running a var scope checker, or documentation building from Ant. Another cool point is that he pointed out things in Ant terminology as equivalent to Coldfusion terms. A lot of the tips and tricks were really useful; I'll have to download the presentation.
I have to admit I was kinda high for the rest of the day after my presentation. I floated through Matt Woodward's Michael Collins' and Mark Mandel's presentations. I got things out of them, but I have nothing to offer on the presentations. That's not a reflection on the presenters. I was just too jazzed up. I'll report more tomorrow.
Meanwhile I struggled with and won getting automatic tagging via ant to work on my machine. I have to say, I've really drunk the KoolAid about it, John Paul Ashenfelter is my new hero.
The keynote certainly started with a bang, as Jason Delmore pulled a Mary Hart. So the keynote was cut a little short. That was disappointing, but thankfully, no permanent damage was done. Jason was just on the cusp of announcing that ColdFusion was going to an open process for development, getting a public bug tracker among other things. This is very promising!
I wandered into Kurt Wiersma's presentation on Setting up a Solid Level Local Development Environment. I have to admit, I was mostly going to check up on what he recommended, because I had written an article in Fusion Authority Quarterly about the same subject. I had the fear that I was completely wrong or something. Good news for me, Kurt's presentation recommended similar things where we overlapped. His presentation was really solid, with really good recommendations on how to setup your environment. I'm not just saying that because I agree with him, but because he gave really good tips and pointers for configuring your environment. Definitely pull down the presentation if he puts it online.
I skipped the second morning session to work on my presentation.
After lunch I went to Agile Bootcamp by John Paul Ashenfelter. This was a session that I was especially looking forward and it didn't disappoint. John's a great speaker. If I got nothing else out of it, I finally understand tags versus trunks in Subversion now. Additionally, in 20 minutes he did more to help me learn Selenium then I had after a week of trying to do it on my own. In total even if you knew some of this stuff ahead of time, it was extremely worthwhile.
I finished up my day torn between a few great presenters, but decided that I have never had a chance to hear Peter Bell speak and wanted to, so I went to his Software Product Lines lecture. He's definitely a great speaker. Although to a certain extent, Peter's blogging bandwidth is so high that if you read him, you'll recognize most of what he had to say.
I owe a fair deal of success to my various experiences working with Avish Parashar.
He's doing a free teleseminar about using developing and using humor in speaking. I haven't heard this particular talk before, I will be listening to it, but I can attest to his expertise on this matter. Anyone who has a vested interest in let's say enhancing a technical presentation to make it more interesting, would benefit greatly from what Avish has to say.
I figure it's important to note, that he's not about adding a joke or two to your presentations. He's talking adding appropriate and topical humor to presentations. He's also about teaching you to think on your feet, and respond to your audience with in-the-moment humor.
The seminar will be held Thursday, April 17th from 1:00PM EST to 2:30PM.
Cf.Objective is in just a few weeks now. Are you going? Here's why you should:
The content is the absolute best ColdFusion content around. I'm not just saying that because I'm presenting. No introductory stuff, no "Getting started with CFC's," just really stellar content.
The price is right. I think the whole thing, including air fare, hotel, taxis, and food cost me under $1300 last year. That's less than many local training courses, but provides so much more.
Access to the experts. Want to ask Ray Camden, Sean Corfield, Joe Rinehart, Mark Mandel, Mark Drew or one of the other experts something? Well they're usually just hanging out in the halls. They don't bite Except for one of the Mark's. I'm not saying which, but I think you'll find it a pleasant surprise.
Everyone is a student. What are the instructors doing between their talks? Most of them are in other people sessions. I don't know why this strikes me as so cool, but I guess it just feels so much more collaborative than authoritarian. You're not learning from experts, you're an expert by being there, and sharing in the experience. Or I dunno, maybe that's too granola for you all, but I like it.
If you don't go Sean Corfield will hunt you down. You will be Ice-T in his home movie version of Surviving the Game. It's true.
March 24, 2008 Posted by Terrence Ryan at 11:54 PM
That's right, today is your last day to get reduced prices for the WebManiacs conference. After today, the only way to get a reduced price is to take a picture of you flashing your gams, send it in, and hope the guys and gals at Fig Leaf approve.*
Of course, you want to go, and see me speak about Air and SQLite, so sign up and get that reduced pricing.
* Actually, I'm fairly certain that won't work. And gams are legs, for those of you who didn't grow up during the Great Depression.
March 14, 2008 Posted by Terrence Ryan at 11:22 AM
I got to participate in the CF_Rountable, a new format for the show where a bunch of ColdFusion community members talk about various geeky topic fodder. This week's group was:
It was a tremendously fun to participate. It was also impressive to see the amount of work and effort that Matt and Peter put into the podcast. They deserve a lot of credit for making it look effortless.
If you get a chance to participate, or see a call for participation, do it. You won't regret it.
Come to think about it, you should probably listen to it too. You won't regret that easier.
March 11, 2008 Posted by Terrence Ryan at 11:45 PM
The ColdFusion community is aflutter with news that Blue Dragon has gone open source. Many other voices have chimed in on this. But I feel like I have something different to say.
Regardless of the any business gains that Blue Dragon gets from doing this, I don't think the community will get a tremendous benefit from this.
I'm pleased to announce that I've teamed up with Mark Phillips and the guys at Vertabase to publicly release ExportReports.com.
What is ExportReports.com, you ask?
ExportsReports.com is a site that enables users of the 37signals product Basecamp to export copies of their projects to a PDF file. Before ExportReports, a Basecamp user could request a backup of their site, and receive an XML dump of their project. Now, through our site, a user can ask for PDF exports at will. It's perfect for either ongoing status reports, or an end of project knowledge dump to a client.
We do charge a small fee, but for the first month, we are running at reduced rates.
Technology
ExportReports was written with Adobe ColdFusion, and uses the Basecamp API's provided by 37signals. Three factors led to us choosing ColdFusion:
We needed to consume webservices, and ColdFusion makes this really easy.
We needed to work with PDF's and ColdFusion pretty much rocks the PDF.
Let's face it, I think ColdFusion rocks.
So, wish me luck on this commercial endeavor. If you're a Basecamp user, I hope you like it. If not, become one, it's a fantastic product. Then use ExportReports.com.
I few days ago I came across this post at Signal vs. Noise. The first item is about a clock that tells you the approximate time - for example 11:59 is "Nearly Twelve", 12:30 is Half Past Twelve, etc. etc. The idea is, "Do you really need to know it is 12:53?" This clock gives you the amount of precision that you actually need when dealing with time.
I thought it was kinda cool, but I would never buy one. However when I thought about it, I realized it would make a good AIR application.
After thinking about I decided to do it because:
It's a simple thing to write
It could use a database
I have a Air and SQLite presentation to prepare
All of these things added up to me writing the thing in about a day. Here's what I did:
Filled a SQLite database with times and descriptions
1 = Just After
15 = Exactly Quarter Past
59 = Nearly (Next hour)
Used HTML, JavaScript, and an Image to build the UI
Got rid of the default Chrome
Used Air Methods to query the database.
Placed taskbar items that allow you to:
Close
Force app Always on Top
The amazing thing to me was how easy it was to do. The actual app worked relatively quickly, most of my time was spent getting the details like icons, and text placement correct.
So if you want to know about what time it is, download your copy of About Time.
Disclaimer: This totally is "an Air app that didn't really need to be". I get that. I figured someone else might like it, or at least want to look at the source.
I'm working on someone else's code base, and found that they were posting forms to themselves. However they had hard coded the form template names into the code for the form. Like the following:
<cfformaction="index.cfm"method="post">
This is a bit of a pet peeve of mine because it tends to make the code very un-portable. What happens if you rename the file "dosomethingelse.cfm." Now you have to go back and change the file name and the reference.
It was a quick proof of concept application, so I don't fault the author. But they just aren't lazy enough.
I prefer doing it this way:
<cfformaction="#cgi.script_name#"method="post">
It's highly cut and paste-able, and you never have to worry when you rename your templates. If you aren't using cfform, you can still do it, just wrap the form element in a <cfoutput>.
Now, I imagine that I will get a comment that says something about not trusting cgi variables. It works with every flavor of IIS and Apache that I have ever worked with. Anybody see any gotcha's doing that.
I was talking last week about using XML to act as an intermediate step in building your documentation (Automating Documentation and Automating Documentation Part 2). It dawned on me that I could also share my technique for building release notes.
I use Subversion. I've gotten positively anal about commenting when I make changes. So if you were to take the history of my SVN commits, they make pretty decent release notes. The trick is to grab them and automatically turn them into documentation.
SVN makes this pretty easy. It takes one command to grab all of the changes. It takes one switch to make the change export as XML. Once that is done, manipulating the content in ColdFusion is a breeze. I do it using <cfexecute> and svn.exe, below is my code:
<cfset svn.wc = "[path to svn working copy]"/>
<cfset svn.exe = "[path to svn executable]"/>
<!--- -v = verbose --xml outputs it as xml --->
<cfset svn.arg = "log #svn.wc# -v --xml"/>
<!--- get contents of SVN history --->
<cfexecutename="#svn.exe#"
arguments="#svn.arg#"
timeout="30"
variable="changes"/>
<cfset changes = XMLParse(changes) />
<cfoutput>
<cfloopindex="i"from="1"
to="#arrayLen(changes.log.logEntry)#">
<!--- lxml = LoopLocalXML (shorted for display) --->
<cfset lXML = changes.log.logEntry[i] />
<dl>
<dt>#lXML.XmlAttributes.revision#</st>
<dd>
<ul>
<li>#lXML.author.XMLText#</li>
<li>#lXML.date.XMLText#</li>
<li>#ParagraphFormat(lXML.msg.XMLText)#</li>
</ul>
<p>Files Effected</p>
<ul>
<cfloopindex="j"from="1"
to="#arraylen(lXML.paths.path)#">
<!--- lPaths = LoopLocalpaths --->
<cfset lPaths = lXML.paths.path[j] />
<li>
#lPaths.xmltext#
(#lPaths.xmlattributes.action#)
</li>
</cfloop>
</ul>
</dd>
</dl>
</cfloop>
</cfoutput>
In my build process, I use <cfsavecontent> and <cffile> to write the content to a file, and then use ANT to call the CFML page that creates the release notes - voila, release notes are now part of every build, with no extra work on my part.
February 19, 2008 Posted by Terrence Ryan at 10:53 AM
This sent a co-worker down a wrong path yesterday, so I thought I would blog it in case it tripped anyone else up.
There was a problem with one of our SQL servers yesterday. (It was down a long time during a routine patch and reboot due to extra stuff in a Microsoft Tuesday patch.) In trying to troubleshoot the issue, one of the administrators saw errors in the event logs coming from the ColdFusion ODBC Agent.
We are using default driver for Microsoft SQL Server in the drop down on the Data Sources page. Therefore, we were using JDBC driver and weren't impacted by the ODBC error. The error message was a red herring. It took focus away from the real problem, namely that the database server hadn't come back online yet.
Going further, as far as I can tell all of the defaults on that page are JDBC drivers, with the exceptions of "ODBC Socket" and "Microsoft Access". According to this Damon's comment on this blog post, the "Microsoft Access with Unicode" doesn't even need the ODBC driver. So I would say, unless you are doing coding against Access databases, or a known ODBC only product, you probably don't need to install the ODBC services; especially since you can always install them if you need them.
I'd be interested to know if anyone violently disagrees, or if this has been said authoritatively somewhere, and I just not up on my Google-Fu.
February 14, 2008 Posted by Terrence Ryan at 10:16 AM
For this example, I am sharing the code for documenting "steps" in Squidhead. Steps are operations that do one thing, like generate stored procs, or ant scripts, or email developers. They are powered by cfm templates in a specific folder. Once there they can be referenced through in the project's config file. The documentation for them is included in the download for Squidhead, and can be viewed online (Squdihead - Steps).
So after the jump, here is the code for creating this documentation.
One of the things that I've been doing lately is writing reference documentation for my projects. Squidhead has an extensive set of configuration options, and an internal project has a custom XML format. I thought I would share the method I've come up with to make it much easier for me to do.
The problem with this type of documentation is that is really easy to do once and then not keep up to date. When coming up with a solution, it had to be repeatable and additive. You could just read in all that information and recreate dynamically from scratch, but that means you can't manually alter the documentation. I was looking for something that would basically just remind/force me to document new options or files. With that in mind here is what I do:
Assume that I am documenting a set of configuration files
Create an XML file where each file to be documented is a node
Do a directory list of the files to be documented
Grab the name of each file
Check to see if a node currently exists in the XML for each file.
If not I add a node named after the file
Create blank sub nodes for "documentation," "notes," or "required" or whatever
When that pass is done:
I scan the XML
I check for blank sub nodes.
If any exit I throw an error
I then add this process to my ANT build for the project. Now every time I go to build the project, the documentation gets scanned, added to if needed, and I am prevented from moving forward until I document new changes.
This turned documentation for me from an incomplete mess of a task that takes two hours or so every few weeks to 5 minute maintenance step every time I build.
February 8, 2008 Posted by Terrence Ryan at 9:29 AM
First of all thanks to all of the people who have either promoted or contacted me about BasecampCFC. I am really excited about all of the interest. As of now it's been mentioned at:
I was talking with someone recently about unit testing. His dilemma boiled down to the idea that he knew unit testing was one of those mythical "Good Things" but he couldn't bring himself to do it; it seemed like such a large commitment in time. I've been thinking more and more about this, and I have come to the conclusion that the time factor in unit testing is actually a myth. Here's why I think so.
Do you write code, and declare it finished when you are done editing it? I hope not. No, you go to your application and test the page you just changed through your browser. If you're working on a CFC, maybe you go to a page named test.cfm, on which you have a few CFC calls and a CFDump. You then looked to see if the results you got conform to the results you expected. Did you do that? Then you just unit tested! The only difference between that and a formal unit test is that you throw away the test after you were done writing that piece of code.
I propose you formally unit test instead. Instead of throwing away that test code, put it in a formal testing framework. You'll probably have to change it a bit to get it to work with one of those frameworks, but the learning cost for doing it this way is much, much cheaper that TDD. Once you do that, you'll never have to worry about breaking code again because you hold on to every test you've ever written. Well, okay, you'll still worry, but you know as soon as you do it what code you've broken, which is a much better place to be at.
I think a big part of the underlying misconception comes from the fact that most discussions of unit testing include a description of Test-Driven Development (TDD). That is the system were you figure out how exactly your code should behave, write tests to check for that behavior, then write code that behaves in a way to pass all of your tests. That is going to change the amount of time you spend on development (at least up front, where we tend to myopically be focused.) More than just a hit in terms of development time, it's a hit when it comes to spending the time learning it. Mind you, I'm not saying that TDD is bad; it's just a paradigm shift, and a big one at that.
BUT that doesn't mean that unit testing IS Test-Driven Development; TDD relies on unit tests, not the other way around. Go ahead, write your unit tests after the fact. No one will know. In fact, many unit tests get written in response to bugs, even when you are doing TDD.
Another misconception is that you have to test everything you do. Some things work better with formal unit testing than others. Yes, with mock objects and development databases you can unit test anything, but that makes the learning curve even steeper. Screw that; don't make it harder for yourself. Small components with a limited range of functions are the easiest to start to work with. Examples usually include some sort of calculator, or other such item that I never use in actual code. So here are my recommendations for low hanging unit testing fruit.
Authentication code, specifically that which test usernames and passwords (as opposed to session management)
Utility code, like a phone number formatter, or custom date converter
Parsing code, like code that takes a custom XML format and converts it to a usable format
Problematic code, code that breaks every time you do an update.
So start moving your informal tests to a formal unit tester. Start with the small stuff and don't worry about testing everything. And for god's sake don't think you have to reach for TDD to be successful with unit testing. Somewhere between where you are and where you are heading is a much better place.
In case you want to know more about unit testing and ColdFusion, check out the ColdFusion unit testing frameworks:
I've been using Basecamp for freelance consulting and I absolutely love it. I have one problem with it, once you shut down a project the client can't get any of their materials. It would be nice if you could export the entire contents of a project, compile it into a .pdf, and ship it off to a client as part of a project closeout.
They have a pretty thorough API, and I happen to know a language that can make pdf's pretty easy. So I figured I could make my own solution, and I did. In doing so, I had to create a service CFC for the Basecamp API. Since there wasn't one when I looked around for it, but there were a few questions about one, I figured I would share it on RIAForge, and I have. You can download Basecamp CFC from there now.
A few things to note:
I implemented all of the data retrieval methods
I implemented create, update, and delete methods for comments and messages
I have not implemented create, update, and delete methods for categories, todos, or milestones
There are not API methods for create, update, and delete of companies and people.
I haven't implemented everything, because, frankly I didn't need it all. But, if anyone uses the thing and really wants them, I will be happy to implement more.
If anybody uses it, let me know.
January 28, 2008 Posted by Terrence Ryan at 9:33 PM
I'm a little late to the party but I got word yesterday that I was selected as an Adobe Community Expert for ColdFusion. I'm a little humbled by the company in just this last round of Community Experts, let alone the whole group.
I'm sure it will be a bit before my information is up on the site, but I just couldn't contain my excitement.
Once I get the hang of this whole "being a dad thing" I'll be posting ColdFusion content regularly again.
Thanks for letting me in, Adobe.
January 23, 2008 Posted by Terrence Ryan at 10:01 AM
Avish Parashar, a friend of mine, is starting a new business venture. It's a consulting and training company which is directed at teaching technical people non-technical skills. You know, those elusive "soft skills" you hear about from time to time.
I recommend Avish and his training in the strongest terms possible. I've worked with him in this capacity for eight years getting guidance on courage, creativity, communication, and influence along the way. I have definitely enjoyed the fruits of applying his philosophy and techniques to my regular working life.
Anyway, check out his site, simpleITSuccess.com, and if you are even considering it, drop him a line. You won't regret it.
January 21, 2008 Posted by Terrence Ryan at 4:32 PM
Less than a year ago, I went to cf.Objective for the first time, and came back with a list of items that I wanted to see myself do, because I was introduced to them at the conference. I thought I would do a quick public coming clean about my progress.
Stop spreading rumors that the man saying he is Sean Corfield having the real Sean Corfield tied up in his hotel room.
My progress:
I started using ColdSpring for dependency injection in a few of my projects. I haven't reached by goal of using it for Aspect Oriented Programming yet. So that will go back on the list.
I refined Squidhead to work against multiple DBMS's and to understand foreign keys; making is a real solution for at least me.
I failed to start using a real UI framework. I would still like to, but I've been lazy. I need to be more disciplined. I really want to start using either Fusebox or ModelGlue.
I think I've switching from thinking about objects as objects first, and then going into the database to represent them, not the other way around. Could I do better? Sure. But I am much further ahead of myself a year ago.
I switched to local development solely. No more remote servers. Feels great, I never want to go back. Thank you, Mark Drew, your "car with a spike on the steering wheel" analogy changed my professional life.
I don't spread rumors about Sean's identity anymore. In part, Sean finally updated his picture. In part because I heard if you make any sort of fun of him, he will track you down, and shave a half dollar sized bald spot onto your head. That man is dedicated! And a Philadelphia winter is much, much colder with a mini-tonsure. Trust me.
So that's it. I'll hold off on making a new list until after cf.Objective 2008.
And if you aren't going, don't worry, every ColdFusion blog will be full of stories of how awesome it is. So, you know, that will be just like being there.
January 16, 2008 Posted by Terrence Ryan at 5:52 PM
I skimmed it a few months back when it came out but never thought about it in terms of the ColdFusion community until I saw this link at Daring Fireball applying this phenomenon to Apple.
Basically the gist I get from it is that profitability is more conducive to long term health of a company than market share. It's not proven, but if it is true it puts the ColdFusion market into a particular light. If what is true for companies is true for products, it might not matter to ColdFusion's long term health if it steals market share from ASP.NET or PHP. ColdFusion's long term health might be in its profitability, which according to Adobe has been very good.
Market share is still important to us, as it helps determines availability of work. But this phenomenon might a good explanation for why what we see Adobe doing with ColdFusion doesn't always match up with what the community wishes it would do.
January 14, 2008 Posted by Terrence Ryan at 11:49 AM
I got word tonight that I will be speaking at cf.Objective() 2008. Needless to say I am thrilled, excited, and a little intimidated. Cf.Objective, in my experience, has the most advanced content of any of the various ColdFusion world events. It's a lot to live up to, and almost everyone there blogs, so if you screw up big it's not like you can keep it under the radar.
My topic is "Selling Professional Development Techniques at a Hostile Shop."
Here's the abstract:
You've started using Subversion, you've drunk the frameworks Kool-Aid, and you go so far as to use an Ant script to launch CfEclipse. There's only one problem, your co-workers don't want to join you. Worse still, your boss doesn't see the big deal, and upper management starts an anti-framework club. You don't want to leave but you can't fathom staying at a workplace that doesn't embrace progress. What do you do?
You leave the technical behind, dust off those so called soft skills, and turn to politics to get the job done.
This session will help you to identify all of the players on the opposing team, figure out their issues, determine what techniques to use to change their minds, and avoid turning into Machiavelli in the process. By the end of the session, you should have a set of concrete tactics and strategies to go back to your organization and start converting the masses.
The basic gist of the session revolves around the question: What do you do when your co-workers or management reject your efforts to introduce "professional development techniques?" What are "professional development techniques?" For the purposes of this talk they include (but are not limited to):
Frameworks
Version Control
Code Reviews
Unit Testing
Company specific Best Practices
Automation
Code Generation
It's a question I've found myself asking from time to time over the past few years. I've had to make find my own answers for it. My hope is to help make it easier for others.
Obviously this isn't a technical presentation, but I hope to keep it practical instead of theoretical by providing concrete tactics and strategies to employ.
I have the outline mostly ready at this point, but if anyone has any specific problems or scenarios they would like advice on, please feel free to drop me a line either in the comments or through my contact form.
December 20, 2007 Posted by Terrence Ryan at 12:31 AM
I've been a little busy with the newest addition to my family, but I wanted to drop a line about an upcoming conference appearance.
I'll be speaking at a session at WebManiacs 2008 on AIR and SQLite. My session is on the first day of the conference, which runs from Monday May 19th until Friday the 23rd. It's shaping up to be a great conference, and I'm a bit humbled by some of the other names that will be appearing. I don't know how I got on the speaker's list, but however it happened; I'm very excited about it.
December 13, 2007 Posted by Terrence Ryan at 12:02 AM
It's been a little while since I've talked about new features of Squidhead, so I figured I would take the opportunity to blow my own horn.
New features:
Oracle Support
Linux Support
Linking table support
FKCrazy Application template
Rudimentary ColdSpring Support
Squidhead will run against Oracle 10g. It alters its model a bit to create stored procedures within packages, as this seemed to be in keeping with Oracle Best Practices.
Squidhead will run on Ubuntu. I haven't tried it in other flavors yet, but I can't tell why it wouldn't.
If you follow the convention of naming tables [table1]To[table2] and have the primary keys from table1 and table2 as foreign keys, Squidhead will recognize the table as a linking table. It will create stored procedures that pass queries through this linking table to create relationships between linked tables.
FKCrazy application will use the linking table information to automatically create interface that uses all of the foreign key relationships to add and delete child records. It can do this in a one to many relationship, or in a many to many relationship. Translation: If you've seen my Facebook in 17 minutes presentation - everything I did manually at the end now happens automatically. So if I did it today, it would be more like Facebook in 12 minutes.
Squidhead can create its own ColdSpring configuration files. Not earth shattering but makes integrating a Squidhead application with an application already in ColdSpring much easier.
So there you go, quite the update over the past few weeks.
November 21, 2007 Posted by Terrence Ryan at 12:31 AM
I made a little update to the CFAir compiler package. I tweaked the generated application to be a little more complicated, and CFAir still works on it. There's a screenshot to the right (If you're own my site.)
November 21, 2007 Posted by Terrence Ryan at 12:04 AM
I made some changes to the CFAIR compiler project.
Added some documentation
Fixed a bug that caused the first run of the app to not create an air file.
Made sure that images referenced by ColdFusion CSS are imported
Additionally I added a screenshot of the image to the RIAForge site.
So check out CF Air Compiler, and please let me know what you think of it. Is this worth developing further? Or should I just wait for Centaur? Anybody have any suggestions or ideas on how to proceed?
November 14, 2007 Posted by Terrence Ryan at 1:43 AM
I was inspired by Ben Forta's post on creating AIR application from ColdFusion. I felt like there had to be a better way than just copying the source of ColdFusion generated HTML files. So I started working with it and came up with a proof of concept project on RIAForge: CF Air Compiler.
I wrote a simple application called "testapp" that just binds a CFGrid to the results of a CFC call that returns a CFFeed of coldfusionbloggers. This is the application that will be packaged into an Air application.
I used CFHttp to grab the ColdFusion page outputted as HTML and move them to a repository. Then I used ReMatch to find all of the used CFIDE javascript files, css files, and images, and copy them to the repository. Then I used ReMatch to grab all of the cfc calls and convert them to fully qualified url calls.
The second part was a little easier. All it required was wrapping the adt.bat in a CFC wrapper. It just has two methods: certificate and package. They correspond to the options for the adt.bat file. I used that to compile the application into AIR.
There were a few challenges with it. I haven't figured out a way to get to the images used in CSS. I could just grab them indiscriminately, but I want to do a little better, expect an update after I think about it for a bit. Also the CF JavaScript evidently tries to do some things that violate the security model of the Air Runtime. It required wrapping the ColdFusion generated html in an iframe. To read more about the issue, you can check out the Air Wiki.
It's not perfect code, but I figured I would at least get it out there and maybe someone smarter could take it a little further. Check it out, please feel free to offer suggestions and criticism.
November 10, 2007 Posted by Terrence Ryan at 2:34 PM
Over the past two weeks I've been struggling with adding support for Oracle in Squidhead. (Expect a release early next week.) Oracle was more different from both Microsoft SQL and MySQL than they were from each other. It got me thinking about the three and their various pros and cons for code generation, and their pros and cons for me doing code generation with stored procedures. I figured it could make a good blog article. (Or someone could see my post and say "Hey you didn't have to do all that because of the blah command!")
Microsoft SQL
This was the first one I started with, so the others are being compared to it. It comes with the built in stored procedure sp_help, which is absolutely brilliant. It gave more information for tables than I ever needed. It also gives most of the information for a stored procedure that I need. Although there are a few things lacking which made me have to resort to using sp_helptext, and then parsing the actual stored procedure. I had to do this to get the number of result sets that a stored procedure returns. (Because if a stored procedure returns more than one record set, Squidhead writes the method to return a structure of queries instead of just a query. ) Also I had to do this to get the metadata of the arguments being passed to a stored procedure.
MySql
Of the three this was the easiest to do. I had a flash one night ("just implement sp_help's queries in MqSQL") and it took me less than 24 hours to add it. Nonetheless I still had to query a lot of system tables directly to get the results I wanted.
There are few other limitations that bug me, but they aren't related to code generation. Things like stored procedures not being able to take default values in their inputs, and views not being able to contain subqueries. I'm sure as those features mature though, we'll see better results there.
Oracle
Finally, we reach Oracle. It took me a week of hair pulling, keyboard slamming and muttered curses to get it right. But finally I did.
What I didn't like:
One has to create a cursor to contain output recordsets for a stored procedure. That's so different than the other systems that I wanted to kill someone. Although, I must confess it makes counting output record sets much easier.
That everything is limited to a name length of 30 characters. So I had to get creative with how to deal with stored procedures with names like usp_entryToComment_list_foreign_key_labels. The solution I came up with was to abbreviate them and rename them higher up in the Squdihead stack so that the functions have the "correct" names.
What I liked:
Packages. Packages are sort of like classes or CFC's for Oracle operations. The encapsulate code into discreet chunks. I basically create a package for every table so my stored procs have names like ENTRYPKG.READ which is better in my mind than usp_entry_read as that's just a way I use to group and sort stored procedures anyway.
The sheer amount of data in the various data dictionaries. I don't have to parse any code strings to get any metadata. That's much easier.
"CREATE OR REPLACE." Truly awesome. Cuts down on the amount of steps I have to do to recreate a stored proc or package. I wish I had known it exists for MySQL.
Conclusion
It's kinda funny, and it may be cognitive dissonance talking, but of the three, I really like Oracle the best for code creation and metadata. Overall, I still lean towards Microsoft Sql as it is the one I know the best. Also whatever your thoughts on Microsoft Sql Server Management Studio, it's so much better than SQL developer for Oracle. But that's a completely different topic.
November 3, 2007 Posted by Terrence Ryan at 7:10 PM
I'll be going over the reason behind the application and what it can do. As for the demo, have you seen my Facebook in 17 minutes demo? Well, I'll be doing that, in about half the time. (I've made some improvements to Squidhead in the interim.)
November 1, 2007 Posted by Terrence Ryan at 9:54 PM
Simply stated, I use ColdFusion because it is the most productive language I have ever worked in. I have done more, in less time with ColdFusion, than I have ever achieved in any other language.
Over the course of years at my job I have had to do work in ColdFusion, Perl, Php, C++, Python, and Java. I don't claim to know any of them; I just had to work in them. None of them have allowed me to build things as fast or as easily as ColdFusion.
Those languages I stated before, of all of them, I used Perl the most. I've spent more time figuring out how to do the few things I really know in Perl, than I spent learning ColdFusion. Part of that is Perl itself, part of that is the sheer sadistic joy that Perl programmers take in making even their sample code undecipherable to the non-initiated, but most of it can be attributed to ColdFusion's true ease of absorption.
I remember something a student interviewing for a co-op position said to me:
I wish I hadn't learned ColdFusion first. It made me expect all languages to be that easy to learn.
Some, (like this recent post from Kyle Hayes) have termed this a weakness with ColdFusion. But that should be considered strength of the language, people want to work in it; people expect other languages to be so accessible. These features should be embraced in the rush to get more users in the door, not thrown away.
There you have my 2 cents, please feel free to disagree.
October 8, 2007 Posted by Terrence Ryan at 11:36 AM
I've long thought about doing a blog in 15 minutes demo of Squidhead. But come on, everyone's done one by now, right?
Then I thought about ColdFusion 8 and its image capabilities, and the image CRUD that I've added to Squidhead and thought maybe a facebook type application would be more compelling. So I did it, and put it up on Google Video. (cause I couldn't get it under 10 minutes.) Then I saw it on Google video and was repelled by the quality of the video. So I have few options to watch it below.
I show off three features of Squidhead in the video:
Image CRUD interface
Foreign Key usage
Scaffolding your stored procedures.
If anyone watches it, please let me know what you think.
UPDATE: It appears that the Flash Version will cause your computer to crash. Sorry about that. I will have a replacement up at some point in the very near future.
My last day at Max was marred by the technical problems. I was going to give a 5-10 minute demo of some of stuff we've done with ColdFusion 8's Exchange features. My laptop died right before I was to start, then I couldn't get my laptop's VGA to display on the projector at the same time. I totally fizzled out. I have to thank Jason Delmore for covering for me, and trying to explain to the audience that I wasn't a complete idiot.
I then wandered into a session named Best Practices for Creating Great Web Experiences. I was a pretty interesting view into the interworking of a design team. I found it interesting because it was so far afield of what I actually do.
I then wandered around for awhile and spent some time in the community area. There I demoed the exact thing I was supposed to demo at the Boot Camp, basically deleting all of my work contacts from Exchange and letting my ColdFusion application repopulate them. At least someone saw it.
October 5, 2007 Posted by Terrence Ryan at 8:57 AM
My day started at the Keynote. I have a few random thoughts about it.
Bruce Chizen would be pretty bitter about being the rich and famous CEO of Adobe if he didn't enjoy it so much. He made me feel guilty though for continuously looking up his salary for one of my work projects. It's impressive.
Scene 7 does some absurd stuff with dynamic imaging.
Share looks promising
Thermo will be absurd if it does all it promises. Photoshop Composition to Flex application in one click.
Next version of ColdFusion is code named centaur. My supposition is that it is so named because if angered, it will shoot you with an arrow, and then trample you to death. It does make me feel a little afraid that they will strap a horse's body on a shirtless Ben Forta, ala "Scorpio Man." I am disturbed.
I sat through Sean Corfield's session on Design Patterns, it was simply tremendous. I tend to be a fan of Sean's but I'm not exaggerating. He did a great job of explaining the theory and the concepts behind patterns. Even though I thought I knew them already, he did bring a new perspective to the whole thing.
I also attended Ryan Stewart's session on Air and PDF integration. It looked interesting, but I have no idea why the hell you would ever do it.
If my day looks a little light, I had a minor problem with something back at home, so I had to skip my first session. I also had an opportunity to give an ad hoc demo of Squidhead, so I took it. If for any reason anybody wants a 5 minute demo, drop me a line. I'm always willing.
I finished up the day at Max Awards and Sneaks Session. The following really stood out to me:
Visual Communicator is a niche product that will make video presentations very easily. I think it's going to be a very cool boon to the vlog space.
Photoshop express is just beyond cool. Pretty much everything anyone would need to do to a photo can be done in an online client. The demonstrator completely retouched a photo in under 30 seconds. Crazy.
Hemant presented on ColdFusion publishing to Air. This is something I really wanted for CF since I saw the Air Bus Tour. They've done more with it than I ever thought. You can do online and offline applications. Cooler than what I was imagining.
Flash gets skeletons. Very cool.
C++ on Flash leads to Quake on Flash. Tremendously cool.
Adobe hired that guy who does the dynamic image content resizing.
I ended up skipping the Event, because it didn't really cry out to me, I had to prepare something for the CF Boot Camp tomorrow, and I'm beat from last night.
October 2, 2007 Posted by Terrence Ryan at 9:17 PM
The first was Meet the Team: ColdFusion. I think Sean Corfield blogged about it, and I tend to agree with him. I was fully expecting the crowd to go feral again, but no it was quite cordial. I think ColdFusion 8 being so rich, and the alpha and beta program being so inclusive was definitely a big part of it.
The second was Selling ColdFusion Outside of the Community. I think the biggest thing I got out of it was the idea that the ColdFusion community has to start swimming in other ponds. We tend to form an echo chamber amongst ourselves. Then when something negative is said outside the ColdFusion community piles on and just disagrees. Instead we need to be continuously engaging those outside of the community so that we can build credibility over the long whole. So when we tell them ColdFusion is an enterprise worthy language that can really drive rapid application development, they might just believe us.
Afterwards I lured Steve Rittler and Rob Brooks-Bilson over to the Hilton to have a stogie with Ryan Steward and John Piotrowski.
October 2, 2007 Posted by Terrence Ryan at 12:04 PM
I'll be updating this over the course of the day, so feel free to come back, the contents will change.
For the first time in a few years I did not oversleep at all. I actually made it to see the entire Keynote. There were some cool things to be seen. For me the highlights, in no particular order, were:
Refactoring and profiling in Flex. Finally Flex developers have the kind of detailed performance information that ColdFusion developers have had for years.
Hydra ?? A language that allows Flash developer to write their own effects.
Premiere Express, a web version of Premiere, that while not great for the power editor, would be a huge boon to the amateur video editor.
The sheer plethora of Air application that I want to download and try, specifically:
Adobe Developers Connect which will now keep the introNetworks application for Max up all year round.
Unfortunately, staying for the entire keynote made me late to my first session. With it booked solid this year, if you are in a popular session, and you are late, don't expect a seat, or standing room. I wandered into a few other rooms, but nothing grabbed me.
After Lunch I attended the session given by my coworkers. Before I recommended their session based on knowing them; now I can recommend it on the content. They did a great job of explaining how and why they converted a VB 6 Trading floor simulator to Flex and ColdFusion. I highly recommend it: A Virtual Trading Floor: Bringing Wall Street to the Classroom.
Next I wandered into an Inspire session about the design of Buzzword. It started late and had a lot of technical issues. That was a real shame because Buzzword just looks too good to be true. I signed up for a beta, and I'm hoping to get a test account soon.
October 1, 2007 Posted by Terrence Ryan at 1:24 PM
I'm here, and loving it so far. The venue is ginormous. I was at the Welcome Party, and halfway through discovered that there was a whole half of the party on the other wing of the center. Huge. HUGE!
While at the welcome party I picked up two interesting bits of information.
1. During Ray Camden's Inspire session on Riaforge, I learned that Riaforge automatically makes a zip of your project if you post it to Subversion. Very cool, and will simplify posting Squidhead updates for me.
2. I caught Damon Cooper and had a great talk with him. In the course of that he told me something very interesting about the business side of ColdFusion and Adobe. I don't think he necessarily wanted it spread, and I'm going to honor that. But I encouraged him to show up to the BOF session that Brian Meloche is running (and I'm on the panel,) and let the rest of you in on it. Without giving too much away, let's just say that Adobe as a company is pretty surprised about the success of ColdFusion 8 and that may have very positive implications for its marketing. So, if you see Damon tomorrow, make sure you remind him to go.
I also learned that Steven Rittler smokes cigars, and Rob Brooks-Bilson and I have almost identical taste in TV's shows, but that's probably less interesting to you all.
Looking forward to tomorrow.
October 1, 2007 Posted by Terrence Ryan at 1:26 AM
I think I just discovered my favorite block of code ever. As such, this is a post so that I remember how to do this when I need to do it again, your may not be so impressed.
I was trying to figure out a terse, reusable way of making sure that my application root was mapped to my application name, and that my customtags folder be mapped as a custom tag folder. It had to work with inherited sub application.cfc's and deal with the fact that my application might not be in the root. I came up with this:
I looking forward to it, especially since I disagree with a lot of the solutions I hear to solving the problem. A quick preview or my opinions:
I don't think Adobe has to give away production-ready ColdFusion
I don't think Adobe should sell an IDE.
I don't think Adobe should take over CFEclipse (I'm not against them throwing some pounds Mark Drew's way)
I don't think magazine or journal articles are the problem
My thoughts aren't fully fleshed out, but I think it has to do with the fact that ColdFusion's niche isn't clearly defined. If you're a Microsoft shop, you use a .Net solution. If you're a startup you use Ruby or PHP. If you see yourself as providing enterprise solutions you use full blown Java. Caricatures to be sure, but I think close to the mark.
I think if you asked most ColdFusion programmers why they use it, they would say, "Because it makes my job easy." But people who like things to be easy, is a sort of hard niche to get a hold of, I mean who doesn't want that.
Anyway, these are just ramblings. Feel free to argue with me either here, or next week in Chicago.
September 24, 2007 Posted by Terrence Ryan at 2:00 AM
I've been noodling here and there and have finally put the finishing touches on Squidhead 2.0.
Before I started rewriting, I spent some time developing more applications with Squidhead. I figured out a couple areas of inefficiency and tried to fix them when I could. Creating configuration files took longer than it should and was a bit confusing. I found myself writing Ant scripts for all of my applications. I kept forgetting to test my applications.
Further when I was maintaining the actual Squidhead codebase, some things were frustrating. Maintaining a separate code base for ColdFusion 8 and ColdFusion 7 was a pain in the ass. Maintaining a simple version and a business version was a pain. Adding new features required a series of cascading tweaks because it was poorly architected.
So here are the solutions to all of those issues and a few more for good measure.
New features:
MySql 5.0 Support
It creates Ant Build files for common tasks
It can run CFUnit tests that it creates during its build
It now will use CF8 rich elements it the generated crud *
It now handles images *
It's now a little easier to extend
It's easy to add steps.
It's possible to add application templates
Modified XML configuration allows developer to override certain defaults like form field labels.
New Configuration Builder
New Shiny Web 2.0 looks (Okay, not a feature per see.)
Cheesey Web 2.0 Logos created for every application.
* CF 8 features can be turned off if application will not be running on a CF8 server.
Deprecated Features:
Simple Applications (They are still available, but they won't be updated)
Removed Features:
Threading (Speed Enhancements weren't enough to justify added complexity)
Requirements:
Squidhead: ColdFusion 8
Database: Microsoft SQL 2000 or 2005; MySql 5.0
Generated Application Using MSSQL: ColdFusion 7 or 8
Generated Application Using MySql: ColdFusion 8
Notes:
For the most part, your old config files will still work. However the more changes you made the more likely they are to have problems.
I'm not sure if anyone else has done this but, I was fooling around with trying to get <cfimage> to create a Web 2.0 type logo. You know floating text, with a reflection. I figured it someone else has done it. But I couldn't find exactly what I was looking for.
I'd like to highlight a Max 2007 session: A Virtual Trading Floor: Bringing Wall Street to the Classroom. It's being given by a few of my co-workers here at Wharton (Charles Rejonis, Alec Lamon, and Erin Wyher). I'm not sure about the exact topics that they will discuss, but it's about a pretty hardcore application that simulates a trading floor. Consequently it deals in multiple transactions per second on large amounts of unique user data. This application was originally a desktop application written in Visual Basic and running in a controlled lab. After a few unsuccessful attempts (because the technology wasn't there yet,) the Learning Lab team managed to replace the old application with a RIA version using ColdFusion, Flex and Flex Data Services (or LiveCycle Data Services). They ran into a lot of challenges that truly tested the limits of all of the underlying technology.
I highly suggest this session to you all. It's a great story that responds to the argument: there are some things that RIA's can't do. Because here is at least one seemingly impossible thing they can indeed do.
September 20, 2007 Posted by Terrence Ryan at 12:58 PM
It was up in the air for a bit, but I'm coming to Max 2007. I had a conflict that I'm also bummed about missing, but a few things came up that made it hard to stay away.
I'm staying at the Palmer House. If anybody is up for meeting up and having some scotch and cigars let me know. I should have a good supply with me.
My tentative schedule is below:
Time
Session
Sun 12:45 PM
Flight USAIR 1632
Sun 5:00 PM
Welcome Reception
Mon 8:00 AM
Breakfast
Mon 9:30 AM
General Session
Mon 11:30 AM
The Design Shootout with Adobe Gurus
Mon 12:30 PM
Lunch
Mon 2:00 PM
A Virtual Trading Floor: Bringing Wall Street to the Classroom
Mon 3:15 PM
Inspire Session: Building Buzzword, a New Breed of Word Processor
Mon 4:30 PM
Inspire Session: Lessons Learned on AIR
Mon 7:30 PM
MTT: ColdFusion
Mon 8:30 PM
ColdFusion Developer Hiring 101
Mon 9:30 PM
Fixing ColdFusion Perceptions and Reputation
Tue 7:30 AM
Breakfast
Tue 9:15 AM
Inspire Session: Yahoo! Presents "Examples of Integration
Tue 10:30 AM
General Session
Tue 12:00 PM
Lunch
Tue 1:30 PM
Adobe Integrated Runtime (AIR) Tips and Tricks
Tue 2:45 PM
Inspire Session: Design Patterns and ColdFusion
Tue 4:00 PM
Leveraging PDF within Adobe AIR Applications
Tue 5:30 PM
Sneak Peak General Session
Wed 8:00 AM
Breakfast
Wed 9:00 AM
Boot Camp for Flex
Wed 12:00 PM
Lunch
Wed 1:45 PM
XD: Best Practices for Creating Great Web Experiences
Wed 3:00 PM
Optimizing ColdFusion Application Performance
Wed 4:15 PM
Adobe Integrated Runtime (AIR) Security
Thu 12:50 PM
Flight USAIR 1564
September 20, 2007 Posted by Terrence Ryan at 12:57 PM
I'm working on some improvements to Squidhead, and a few of them relate to Ant. The new version of Squidhead creates Ant build files. In addition to Ant tasks for rebuilding and refreshing the application, there is also one for running all of the CFUnit tests that Squidhead creates.
Since I'm trying to highlight the ability to add steps to Squidhead applications, I was thinking that it might be cool to not just write the tests as part of the Squidhead build, but also run the tests as part of the Squidhead. Including the ColdFusion autorunner for the reports didn't work. Because both CFunit and Squidhead rely on <cfflush>. So I fired up CFAnt to see if it would run. It didn't. It through an error that stated: BUILD FAILED askdef class net.sourceforge.cfunit.ant.CFUnit cannot be found.
I copied the version of cfunit-ant-v3-alpha.jar I use with Eclipse to my ColdFusion8/lib directory, restarted the server and voila: BUILD SUCCESSFUL.
Ant in ColdFusion is cool.
Oh and I imagine the same tip would help you to run CFCUnit tests to run from <CFAnt>
September 19, 2007 Posted by Terrence Ryan at 1:49 AM
Over the weekend I got a notice that my hosting account with my old vendor had expired, and that it was time to renew. I had a lot of sitting around and waiting time this weekend, so I decided to consider if I should go with a different host. After much deliberation, I decided to switch to YoHost. I switched for the following reasons:
After being bought by a larger company, my old host's support took a slight downturn in promptness. I had read good things about the customer service of YoHost. (So far they are all true.)
YoHost had ColdFusion 8 hosting available.
For slightly more than the cost of 2 sites at my old host, I have a plan that provides me with 10 sites. I appear to be completely over, but who knows what glitches await me.
September 17, 2007 Posted by Terrence Ryan at 12:52 PM
Caught this on MXNA earlier today so sorry if you are seeing this twice.
Want to "Airify" any website. Like Gmail, or FullasAGoog?
Try Airifier from Arc90. It's great for making a proof of concept of a site to see if it would be appropriate to spend resources on making it an Air application.
September 12, 2007 Posted by Terrence Ryan at 2:58 PM
I ran into a problem recently where a completely valid XHTML 1.0 transitional site was rendered incompliant by the addition of <cfmenu>. It seems that <cfmenu> causes compliance to fail in two ways:
First, it adds JavaScript to the "OnMouseOver" and "OnMouseOut" attributes of its menu items. To be compliant, it should be adding them to the "onmouseover" and "onmouseout" attributes. There's an easy fix to this. Inspired by Ben Nadel's post on altering the output of the writeToBrowser feature of <cfimage> I just used <cfsavecontent> to capture the menu, and then alter it, as listed below:
The img created in that code doesn't have a alt tag.
Now the interesting thing here is that isn't actually a div that's created, it's only JavaScript that will at some point create those elements. I think technically the compliance test is falsely marking this as a violation. But try explaining that to a client who demands compliance without understanding the theory behind it.
Anyway, I can't find a single way around this. Using the OnRequest method of application.cfc was my best bet. I figured I would use to call <cfsavecontent> and replace the offending code like I did above. Unfortunately, this spot of code is directly written to the buffer when <cfmenu> gets called.
I also tried a few getPageContext() functions, but to no avail. I'll be stuck trying to explain this to the client. In the meantime, I filed a bug report with Adobe.
September 11, 2007 Posted by Terrence Ryan at 1:29 PM
I've been having an issue with a quick and dirty development server I setup for a project. I couldn't get Verity operations to run. I checked and low and behold there was no Verity Service installed. I reinstalled ColdFusion, but still no "ColdFusion Search Service" showed up.
Then I tried what I should have thought of in the first place. I right clicked verity_install.bat and chose to run as administrator. That did the trick; Verity is now completely working.
September 11, 2007 Posted by Terrence Ryan at 12:05 AM
Nathan Mische asked a really good set of questions in response to my code review presentation posting. I figured that I would give a longer answer than really works in a comment.
First it's important to point out that formal code reviews are part of a suite of quality assurance techniques. They do not preclude the use of any other, including application design, informal code reviews, testing, etc.
But formal code reviews, a whole bunch of people looking at all of the code, and then having a long meeting discussing it, are relatively expensive. They take a good deal of time from many people who are probably working on their own code, and incurring the cost of context switching by doing so. So my guideline for code reviews is once per major revision of the application. Basically, if you spend a few days doing an update on an application that has already been reviewed, then you probably don't need a formal review. If you and a team of developers spend 4 months doing a revision to the code, a formal review is probably in order. Those are the extreme cases; your organization will have to choose where in between to draw the hard fast line.
As for when to do them We at Wharton do them basically right before the application moves from development to production. This is also the time when we try the application out on the staging server. The timing is dictated by how we've mandated code reviews. To get your application on our production ColdFusion servers you must go through a code review.
Is that the best time? I'm not really sure. I think if you design correctly, unit test, informally review code, and get user feedback from your clients, then it is the right time to do the review. But we don't always do all of that so I get the subtle feeling that earlier might be better, but we'll just have to deal with the timing forced by our mandate.
Anyone else have any opinions on this?
September 10, 2007 Posted by Terrence Ryan at 12:35 PM
Dave Konopka has a post over at his site about a ColdFusion position that is open at Wharton Computing at the University of Pennsylvania, in Philadelphia PA. He's looking for a junior level ColdFusion developer, but will consider hiring a PHP, Ruby or .Net developer and retraining.
I had the pleasure of working with Dave for a little over a year and half, and let me say that Dave's an amazing guy with which to work. Also, he took the .Net programmer retrained in ColdFusion route, so he's not fooling around about accepting other technologies. So if you're even thinking about it, I say take him up on his offer and drop him a line.
I think ColdFusion 9 should be able to produce AIR applications.
Oh wait, I'm should probably preference this I love ColdFusion 8, and I think it's great and the CF team deserves a rest. I do, I do, and they do. I've been holding on to this idea ever since the Philadelphia stop of the AIR Bus tour, and if I don't get it out unfinished, I'll never get it out there.
Okay, so back to ColdFusion should be able to publish AIR applications.
ColdFusion is cursorily related to so many of the technologies that surround AIR. ColdFusion provides an easy webservice infrastructure you need to run remote Flex applications. These remote Flex applications can just as easily be AIR as Flex. ColdFusion 8 can now generate rich controlled HTML and JavaScript driven applications. Just like the kind of applications that can be packaged as AIR applications.
But the direct linkage between ColdFusion and AIR is missing. Its can help but only as an unglamorous background player. It shouldn't be, especially when it can produce so much of what AIR is made from.
I can envision setting something in Application.cfc like This.publishAsAir = TRUE. When the application url is browsed the ColdFusion server compiles all of the CF JavaScript libraries that are used in the application, and adds every page that is specified in another application.cfc setting, and builds it as an AIR file.
How would this work with applications that aren't page based but url string based (like framework based applicaitons)? I have no idea.
How would this deal with pages driven by database results? I have no idea.
How would it hande all of the backend activity of tags like <cfmail> or <cfldap>? I have no idea.
Would this be really hard to do? Probably, but have you seen what they've done with CF 8?
I'm thinking maybe there would be some way of limiting what gets created as the AIR components. Maybe you would have to wrap all of the application parts you wanted to use in a <cfair> tag, and it would prevent the calling of certain tags within it? I have no idea.
So am I nuts, or are the obstacles too high with this?
August 30, 2007 Posted by Terrence Ryan at 11:59 PM
I found a new way to make your administrators life hell.
Create an application mapping to a custom tags directory.
Put a custom tag named "doSomething.cfm" in it.
Create a ColdFusion page named doSomething.cfm in your application root.
Call <cf_doSomething.cfm> in that page.
Browse to that page.
Watch your ColdFusion server die
I kinda feel like I shouldn't bother with a bug report because, well, it was a pretty stupid thing for me to do. And in fairness, it won't crash, it just can't do anything while it's processing that infinite loop.
August 27, 2007 Posted by Terrence Ryan at 9:03 AM
I'm doing some serious thinking about the future of Squidhead, and I some stuff I wanted to run by the small but plucky group of Squidhead users that are out there.
It's gotten a little unwieldy to do updates for both a ColdFusion 7 and 8 version of the feature set. Additionally, the whole business objects and non-business objects version is also getting hard to support. Finally, there are a whole bunch of features I would like to support but require ColdFusion 8. So here is what I am proposing:
Ceasing development of the current version of Squidhead.
Starting a new development track that required ColdFusion 8 for application generation. (But then generated application could run on ColdFusion 7.)
Dropping the non-business objects version of the code.
Once I did that, I could do the following:
Switch database analysis over to use <cfdbinfo> for most, but not all of what I do.
This would make adding support for other DBMS's easier
I'd be happy to hear any feedback you might have on these proposals. Assuming no one objects, I would publish one last version of the old code as 1.0, and then start pruning and working on what I would call version 2.0. (I would also come up with a more standard versioning system.)
August 26, 2007 Posted by Terrence Ryan at 11:36 PM
I ran into a little problem today, and haven't figured out a way around it yet.
I had a page that is slow but changes rarely, a textbook case for <cfcache>. So I added the caching statement, and ran it. It looked perfectly fine in Firefox. I went to look at it in IE 7, and the CSS was screwed up (supposed to be a centered aligned design, now all the way to the left).
I couldn't figure it out. I looked at the source code, no differences. Finally I ran a comparison on the two page sources, and discovered that <cfcache>seems to add a ColdFusion style comment containing the url of the page into source, above the doctype declaration. I couldn't see how that would cause the problem, so I submitted the source to the W3 Source validation service. It informed me that the comment style invalidates the page, because I was using XHTML 1.0 Strict.
As I see it, my workaround is to set the page to XHTML 1.0 Transitional, or stop using <cfcache> on this page.
August 17, 2007 Posted by Terrence Ryan at 12:16 PM
I love the new Custom Tag Paths in Application.cfc feature of ColdFusion 8. In fact I love it so much I'm using it everywhere now. I did run into one problem though. I tried calling an application mapped custom tag from sub folder without its own Application.cfc. The custom tag call bombs. I added an application.cfc that extended the application's root application.cfc, and still no joy. I had to explicitly set the custom tag mapping in the child application.cfc to get it to work.
No big deal, but I figured I would share it.
August 16, 2007 Posted by Terrence Ryan at 11:51 AM
I've been doing a fair amount of work with custom tags and JavaScript DOM manipulation. One of the things with which I've struggled with is organizing my code. Do I put the JavaScript in the custom tag? Do I put it in central .js files? What if the script I've written will only be called from one custom tag and one custom tag only?
Well I haven't worked out all of the answers, but I do have a solution for single use scripts: Use <cfhtmhead> to inject the script into the html header from the custom tag. It keeps all of the connected code together, but still does proper, degradable, properly-separated JavaScript and HTML.
I gave a presentation on code reviews to the Philly CFUG a few weeks back. Then my host died, and I never posted this. I'll try and get the presentation up on the site in the next few days. But two questions arose that I figured I would discuss here:
Do you check the code after the review to make sure developers have made the changes for which the team has asked?
Can developers request a code review?
Both of these speak to a subtler issue. Does your team want to be adequate or excellent? What about each member, what do they want? The answer to this question will inform the answer to the previous ones.
Now this isn't want of these things where I'm using reverse psychology to encourage what I want others to do --- "Well if you want to be only adequate..." Look, not everyone can be excellent. I don't want to get into a whole discussion on where someone brings up "Free Markets" and someone brings up Harrison Bergeron and then we all get angry at each other. My brief statement on this is that there is plenty of value contributed by people who are only adequate.
But it's going to make a difference with a whole lot of things, including code reviews. Those that want to be excellent welcome criticism, because the idea of their product being flawed in any way is appalling to them. It's more appalling than letting other people find those flaws. But really, they like to show off what they've done, and want to be acknowledged by their peers for it too.
On the other hand, those that only want to be adequate don't care if something has flaws, as long as it works. They may try and avoid reviews, but mostly they'll tend to be indifferent to the whole process, and will only do it if they are mandated. Unfortunately once it's mandated it becomes a perfunctory step for them, a hoop to jump through. Some of the more militantly adequate will say things like "Don't bother fixing it; let's see if we can sneak it past the code review."
So, if you have group of developers striving to be excellent, they absolutely will ask for their own reviews (but you might need to let them know they are available) and you won't have to check them afterwards. On the other hand, if your team is on the other end of the spectrum, you might just have to mandate them. Perfunctory code reviews while painful are better than none at all.
As for double checking the code, it comes down to trust. Do you trust your teammates? I say err on the side of trust. Code reviews tend to ruffle a few emotional feathers to begin with. To big brother people afterwards would just add insult to injury. Trust people until they give a reason not to trust them. Obviously if you are doing work with sensitive data you may want to evaluate this on your terms.
But if people have violated your trust, you're going to be glad you followed the rest of my advice on code reviews. That way you'll have page names and line numbers by which to judge whether or not they kept up their end of the bargain.
This tension between adequate and excellent effects many other aspects of your team. I'm thinking you may want to look at this for more than just code reviews. I figured this would be a good place to sneak it in.
July 1st starts the first official day of my new job. I'll be taking on the role of IT Director for Wharton Research Data Services. WRDS (pronounced "words"), as we call it, is a suite of research applications that provide access to financial databases used around the business and business academic world. We resell it to other educational organizations, making it a very important part of the Wharton brand. I'll be taking over direction of the web portion of the application.
My first concern will be the giving the website a direly-needed facelift. To facilitate that we hired Happy Cog to do a kick-ass redesign, that has been sitting unused for awhile. I'm going to get that new design up on the site, by October. As part of that plan, I'm going to be taking on automation and separation of content from design. Of course, I won't be doing this alone. I've got a new staff of which I'm in charge
The technology that drives the site is Perl. There are no thoughts on getting rid of all of the Perl, as it's needed to talk to the SAS databases on the backend. I'll be adding ColdFusion where it makes sense - mostly in a community feature that we are building. Additionally I'm working on what amounts to a domain specific language (in ColdFusion) to automate page construction. Thanks Peter Bell for turning me on to that whole stuff.
It's sort of a bittersweet sort of thing. It's the first move for me in awhile that involves complete change, as opposed to just increasing responsibilities. I give up all my safe ColdFusion cache.
The job of running our ColdFusion environment and providing ColdFusion leadership will be falling to Dave Konopka. I'm extremely proud of him, since I hired him, and now he's replacing me.
While today is my official start date, I have permission to sort of coast through this week and start next Monday. I'll be wrapping up some lose ends from my old job today and tomorrow, and taking a 5 day weekend for Fourth of July holiday.
I still intend to post on ColdFusion, and I'll still be maintaining Squidhead. However, I'm going to generalize the topics a bit. I'm going to talk a bit about my experience as a client to Happy Cog (awesome in short.) Also I'm going to talk about some developer soft skills (like influence), and how to practice them.
I've had to search for this several times in the last few weeks, (ever since Mark Drew pulled me into the dark side that is local development.) I figured if I blog it, I'll always have the answer at hand.
If you are restoring a Microsoft SQL database from a backup onto a new server, and you need to re-associate the server login name to the database username, you need to call the "sp_change_users_login" stored procedure. That will allow you to reconnect them.
I ran into my first inexplicable crash that I eventually traced back to the ColdFusion Server Monitor. Now first off, this isn't a problem or bug with the Server Monitor. This is to be expected. The server Monitor adds overhead to requests, and if you have an intense process, it's going to generate a lot of monitoring data. It's possible that you might reach its limit.
I just wanted to let people know what a crash caused by the monitoring service looks like, because it doesn't give you a message that "You have left the monitoring service on in production!"
I had a long running complicated process crashing on my local workstation. It did work on our communal development server. So it wasn't just the process itself. I thought maybe it was that my laptop wasn't a server class machine. But actually, the virtual machine that we are testing on wasn't tremendously more powerful.
The browser session would error out with a message that said:
500
Java heap space
java.lang.OutOfMemoryError: Java heap space
After digging in the JRun logs for awhile I found this:
javax.servlet.ServletException: ROOT CAUSE:
java.lang.OutOfMemoryError: Java heap space
at coldfusion.monitor.event.MonitoringServletFilter. doFilter(MonitoringServletFilter.java:70) at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46) at jrun.servlet.FilterChain.doFilter(FilterChain.java:94) at jrun.servlet.FilterChain.service(FilterChain.java:101) at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106) at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42) at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:284) at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543) at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203) at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320) at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428) at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266) at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
Of course I didn't bother actually reading this error until just now when I copied and pasted it. It clearly indicates that the problem is in the Monitoring Servlet Filter. In any case, after much trial and error, I turned off memory tracking and then turned off profiling. Once I turned off profiling the error went away.
I had to do a repetitive database task yet again the other day, and I stumbled onto the fact that Ant has full blown support for SQL. The only challenge is getting it to work with the Microsoft SQL we use here. It's not exactly self evident, mostly because I'm not a Java programmer, so I figured I would share the information.
First download the Microsoft SQL JDBC driver from Microsoft:
Obviously, you'll want to use your application's database password to do that. Also, I included the SQL directly, but you can also call a .sql file with statements in it.
There are a few gotcha's:
"Go" intermittently causes issues. Use a semicolon to separate statements
Use [database name] doesn't seem to work
Putting Database passwords in an .xml file will expose them.
Rename build.xml to build.ant.
Make sure you don't expose .ant files to your webserver.
What can you do with this? Well I have a couple of ideas:
Delete rows created by tests.
Run Consistency checkers
In conjunction with an export script, synchronize schemas and stored procedures between two databases.
You may also want to look at the documentation for the SQL Ant Task.
You may or may not have noticed a little unplanned downtime. The webserver that Numtopia.com is on died last Thursday. My hosting provider got ColdFusion up by Saturday. But I don't run BlogCFC like all the other cool kids, I run Movable Type which needs Perl and a special MySQL Perl driver. Getting my hosting provider to re-install it (it was there pre-crash) was an exercise in patience. It took almost a full week for them to do so.
Now I've been oscillating between impatience (I want this up) and understanding (this isn't a business, and I've had to deal with people with custom configs post crash.) I've decided that for ColdFusion hosting, for $12 a month; 1 week of downtime for my ability to post to my blog over the course of 2 years, is probably acceptable.
ColdFusion 8 is now out as a public release candidate, and do I have a lot to say.
First off, I think the ColdFusion team did a great job at adding features across the board that would make ColdFusion a much more competitive product. But I think more interesting is looking at what the ColdFusion team is making easier for you in this release.
ColdFusion has, in my opinion, always been about taking the operations that everyone has to do to build web applications and make them easier. Early versions were focused on making talking to databases easier. ColdFusion MX 6 was about porting the codebase over to Java. You could argue that it was about making ColdFusion easier to work cross platform. That's a stretch, so if you prefer we can say it was a rebuilding release. ColdFusion MX 7 was about making interfacing easier. Between <cfreport> and <cfdocument> ColdFusion gained new ways of output data. Flash Forms was intended to make writing form based interfaces easier. Gateways make ColdFusion easier to interact with in non-traditional, non-browser based ways.
So what does this version of ColdFusion make easier? I've been searching for an answer to that for a few hours now and I think I have a few answers.
ColdFusion 8 will allow ColdFusion developers to create richer, more engaging web applications
ColdFusion 8 will provide powerful new insight into server performance and simplify application troubleshooting
ColdFusion 8 will give developers broader platform support and enterprise integration
Here's my translation:
ColdFusion 8 makes Web 2.0 Easier
ColdFusion 8 makes Administration Easier
ColdFusion 8 makes selling ColdFusion to the Enterprise easier
ColdFusion 8 makes Web 2.0 easier
Cheesy, unliked, overused and unfortunately for me, necessary, the Web 2.0 moniker is unfortunately here to stay. It's about many things. But I've always liked it, because I've always looked at it not from a technology perspective, (It's Ajax, or Flex) but from an authority focus. Web 2.0 is about user content, not "authority" based content. It's about users choosing how to consume their applications, not site owners dictating how to consume it.
One could make the argument, that there are only two types of typical, Web 2.0 user data that ColdFusion has to date, not dealt well with. They are Video and Images. Video is still shaking out, and still isn't addressed by ColdFusion. (Adobe as a whole has direction on this.) But at least on the image side of things, ColdFusion 8 makes it easier to handle with <cfimage> and the suite of image functions.
It has always been easy to do Flex development against ColdFusion, but now <cfajaxproxy> and the JSON functions are making it easier to do Ajax development against ColdFusion. This further separates the choice of ColdFusion from the front end used to access it. This is a good thing, it expands a bit on what they did with 7, but also allows "ColdFusion and Ajax" to be said a lot together in press releases and technical news articles. This is good for us as a community.
ColdFusion 8 does not abandon the interface side of things though. There are a bunch of new display management tags including <cflayoutarea>, <cfpod>, <cfmenu>, <cftooltip>, <cflayout>, <cfmenuitem>, <cfwindow>. This shows that ColdFusion is still trying to make it easier to do things that everyone has to do. This time, they are clearly going after the interactivity of "Ajaxy" sites. Now, in the past, in ColdFusion, these types of interfaces have not always been usable on a forward facing application. This is no longer the case. Not only do they look completely modern and professional by themselves. But if you don't like them, they can be styled by CSS.
Lastly on the Web 2.0 side of things, there is a <cffeed> tag. This makes both creating and consuming RSS or Atom XML feeds much, much easier. Not much to say about it, this is something that all of us have to do now, ColdFusion makes it easier.
ColdFusion 8 makes Administration Easier
The new ColdFusion Monitor tool is perhaps the best improvement to my job ColdFusion has ever made. The ability to track down an errant template is simply stunning. The ability to kill a running template is beyond stunning, it's ginormous. You can actually see the stack trace of a running template if it's causing a problem. You can even see every variable in every conceivable scope in a request. This is truly stunning.
Even though we central administrators love exercising iron-fisted control over our shared servers, it's really nice for Adobe to open up limited capabilities of the administrator to distributed users. I do wish they had made it easier to tie it into a third party directory tool like Active Directory, but I'll take what I can get.
Finally the administrator now has more options for tweaking performance. You can set limits on number of simultaneous page requests, CFC calls, Flash Remoting calls, and web service requests. All of these tweaks do make it easier for administrators to control their environments.
ColdFusion 8 makes Selling as an Enterprise Solution easier.
I've never been one to demand Java like features in ColdFusion. However there are a few areas, where it would be nice if more Java like behaviors were exposed. One case I'm talking about is file processing. ColdFusion 8 now lets you parse files line by line, instead of forcing you to load an entire file into memory at once. But that doesn't even mention the addition of native Zip tools, which now exist. Granted you could have always dropped down into Java to handle this stuff, but the more you force that to be a solution for people, the more entry-level programmers that run into walls.
But, ColdFusion 8 doesn't just play with Java better. Adobe's been hanging out in Redmond. First ColdFusion 8 can call .Net objects like it can Java classes or CFC's. I think a little cooler, is the fact that ColdFusion 8 can talk with Exchange. Granted, I'm a little sad to be out of an expertise, but happy that everyone can now play with Microsoft's groupware offering. I'll probably be saying even more on this feature in the upcoming weeks. But make no mistake about it, this is hands down the easiest way interact with Exchange other than Outlook. It's really, seriously, that good.
There's a lot of touting of the performance enhancements to ColdFusion 8. But in addition to just running faster, ColdFusion 8 allows developers to have more control over the performance of their applications through the addition of <cfthread>. This technology will allow developers optimize sequential behaviors like emailing, or rebuilding static files by running them asynchronously. Up until now, the only clean option for asynchronous operations was the Asynchronous CFML Gateway. It does the job, but is a little unwieldy to use if you aren't an administrator on the machine. <Cfthread> doesn't replace the Asynchronous CFML Gateway, it just allows another option in the continuum of asynchronous operations.
All in all, developers can now make faster performing applications, on a faster platform, which can talk to many more systems now.
Conclusion
This is just the tip of the iceberg. Every one of these one sentence blurbs represents a feature that deserves its own blog post. (They also probably represent years of developer's time.) Additionally there are a ton of features, functions and tags I didn't mention. This is by far the best release of ColdFusion yet.
I published a change to Squidhead earlier today that included an option for Squidhead to write its own unit tests today. These unit tests are compatible with and require CFUnit. Here's a little bit about the reasons behind this.
I originally started fooling around with unit testing because after drinking Pragmatic Programmer Kool-Aid, and attending cf.Objective, it was the next thing on my list. I figured I would be pulling them into Squidhead, as it's pretty easy to tell if Squidhead worked (the application is either written or not,) but it's hard to tell if the created application is working. So I started to write unit tests for my DAO Objects figuring it would be an easy place to start. Once I got one working, I realized it was relatively rule based and could stand to be generated itself.
What it does is:
Create a mock struct of the record.
Create a mock struct of the record slightly different from the first.
Create a record from the mock record.
Read it back and compares it to the source.
Update it according to the different mock record.
Read it back and compares it to the source.
Delete the record
Read again to make sure the item is gone.
All that is wrapped in a <cftransaction> making sure the thing never happened. Additionally it reads in and honors foreign key constraints. It's got some weaknesses: it doesn't like binaries or images; its smalldatetime check is only accurate to the hour; and there are probably more bugs lurking.
Now once I got them working, they were in, but what's the point for users of the application? One should expect that the parts work.
So to make this worthwhile I added some logic that will run any test that is in the test directory structure. So if you're using Squidhead and looking to dip your feet in the waters of CFunit or unit testing in general here's your chance.
If you're wondering why CFUnit, and not CFCUnit, it's because as far as I can tell CFCUnit requires Mach II, and I figured one requirement was better than two.
So if anyone has any suggestion on how to test gateways or dao's I'd be curious. Otherwise check it out.
I figured I'd drop a line about a RIAForge project I just posted tonight.
It's pretty basic, but I figured there might be someone out there who would need the same thing. SvnAuth.cfc allows for programmatic interaction with Subversion authz files from ColdFusion. I know this might not be cool with the philosophy behind SVN. But I'm not really looking to prevent people from updating other people's projects, but rather preventing sensitive information (like datasource passwords) from being seen by people other than the developers.
Anyway, if you're in the small market for programmatic control of an SVN auth file from ColdFusion , check out svnAuth.cfc.
Adam Lehman and Tim Buntel graced us with their presence at the Philly CFUG meeting tonight.
A couple things I really liked:
Tim directly addressed the fear of the CF community that ColdFusion doesn't have a future. Basically "Look at everything we're positioning for the future! ColdFusion is the technology that we're using to drive them all!"
Adam has really refined the examples he uses to explain each feature.
Adam also really did a great job of answering earlier criticisms of <cfexchange> issues. (Not just the ones I leveled at him.)
In general, I'm really impressed by the ability the CF road team shows to alter their presentation in response to the community. They're not just reading the same presentation to you. Well they are reading from the same presentation, but they've definitely changed the talk based on issues brought up by their audience.
figured I would take down the entire list of features discussed to date. Why? So I don't accidently mention a hypothetical to-date-unnamed feature, after the jump:
Over the last few days, between the inspiration I got from cf.Objective(), and some positive internal feedback regarding Squidhead, I was inspired to make some cool additions (Or what I consider cool editions.) I figured I would share.
Business Layer
Dave Konopka advocated for a layer between the DAO and UI for awhile, as I explain in my last Squidhead update. Well he finally got it. Basically it's the place where you want to put all of your logic for dealing with the objects as they will be interacted with by the UI.
XML Structure Cache
I wanted to do a few things to overcome the fact that the database is does not contain enough metadata to handle certain things. But I didn't want people to have to start with XML to start working with Squidhead. Solution: an XML version of the variable structure that Squidhead uses to generate all of the procedures, functions, cfc's, custom tags, and cfml pages for an application.
So what happens is that at some point you freeze changes on the database, then you set Squidhead to use the disk cache instead of the database. It will then allow you to change a couple of things in how the application works.
Currently you can only change three things (and have the change do something useful):
DisplayName on database columns that will show as labels on all UI components instead of the name. ("First Name" vs f_name).
OrderBy on tables which will alter the order of the default List elements
ForeignKeyLabel the column which will be substituted for the primary key, in all tables that link to this table via foreign keys.
Which leads me to...
Foreign Key Support
Squidhead now understands foreign keys. Here's how it works:
Form UI - On forms that interact with tables with foreign keys, Squidhead will produce a select box of the aforementioned "foreign key labels."
List and Read UI- These components now call separate stored procedures that properly join the requisite tables to show the appropriate "foreign key label" in lieu of the actual value.
I haven't done anything with children objects or anything yet. Basically the change was to make the UI a little more useful.
My next pass of updates will be documentation related, as I've fallen behind.
First off, it was an awesome conference for no other reason than I got to meet a whole bunch of people I know only by their blog, or blog comments. Second, I now get the allure of a Twitter back channel. (Even if it annoys some of the people on my Twitter list who aren't ColdFusion geeks.) Third, I haven't been this mentally stimulated by a work related conference, like ever.
This conference was awesome for the sheer access it gives attendees to the people who are leading our niche of web development. There's something very convincing about Mark Mandel advocating Transfer, or Joe Rinehart showing off Model-Glue:Flex. And there's something really entertaining about watching Mark Drew curse and compile his way through preparation for a CfEclipse demo.
But the biggest thought going through my head now is "What do I do, now that I know everything I do is wrong?" Granted that's an exaggeration of the truth, but it's certainly the feeling I have. But a more productive version of this question is "How do I introduce all of these great techniques into my regular work?"
Stop spreading rumors that the man saying he is Sean Corfield has the real Sean Corfield tied up in his hotel room.
That's a pretty tall order. Of course the smart thing to do would be to accept that there is no way that I can do all of this and therefore not try any of it. (Hold off that on that comment... I'm not just done yet.) So that's not a good attitude, but it isn't an uncommon one either.
I think the actually smart thing to do would be to accept that it's possible that I wouldn't implement all of these any time soon. However, I'm going to try and implement some of these things in bits and pieces where they make these most sense over the next few months.
I've already got a virtual server running a complete development environment, and I maintain that I never saw the real Sean Corfield this weekend...
Oh well, at least I managed to cross one of those off my list.
Paul Kenney: Test driven Development with ColdFusion
Paul Kenney from Adobe took us through test driven development. Testing is one of those things that people (okay I) always nod their head and say "We totally should be doing that" and then do nothing about implementing. I was hoping to get some good incentives or strategies out of this session.
Paul started with the problems of testing. They basically boil down to:
Too little
Too late
Too difficult to run (not automated)
Tips
Programmer Tests (Unit Test)
Written by developer that writes the code
Written before the code that they test
Tests external behavior of components
Acts as a contact
No code without testing
Allow freedom to refactor
Refactoring
Changing internal action of code without altering external behavior
Do so when principles of good object oriented design aren't being upheld
Duplication
Hard to understand
High Coupling
Low Cohesion
Too many switch statements
cfcUnit
Errors versus Failures
Errors you know
Failures occur when code does not act as expected
Charlie Arehart: Understanding, Improving and Resolving Issues With Database Procedure Caches
Charlie Arehart is a really polished speaker. I'm not knocking anyone else, but he's just really smooth.
The main thrust of the talk was about getting optimized query plans through ColdFusion.
Points:
Remember that there is a Database Management System between you and the database
Database driver
Connection Pool
DB Page buffers
Query Plans - Prepared Statement plan
Use SQL Profiler
You can see Execution plans
DB Plan caching
Reduces the amount of processing DBMS does
Instead of computing new plan, it reuses old one.
Some of this data is available in perf monitor.
Use the DBCC stuff in SQL 2005
Performance Implications
Cache requires memory on CF
Not using it requires processor on SQL
MySQL can do some of this now
Couple Gotchas
SQL 2005 might not work if you are using compatibility mode
Prepared Statements can hurt sometimes
When selecting by NULLS
Ben Forta: Keynote Top Secret Scorpio
Ben went over the Adobe buy out and customer worries to start with. He then went into the marketing over view:
Developer Productivity
Integration
Management and Administration
Ben talked about three things to do with Developers and Eclipse
First was the ColdFusion Ajax Application Wizard. Much like the Flex application wizard it creates a simple application using Ajax. He also pointed out the ColdFusion Ajaz Debugging tool. You know how PHP programmers will grudgingly admit that ColdFusion does debugging much better than anything else out there. They're going to have to say it some more; because this thing is awesome.
Second was the Eclipsed based ColdFusion Debugger. This feature has never really excited me. But seeing it in action, I can really see it being useful.
Third was the new integration of Flex Data Service into ColdFusion. It's now being called LiveCycle Data Services.
New gateway for pushing data to LCDS from ColdFusion
LCDS is now part of the ColdFusion Install.
Data Services can be consumed by technologies other than Flex.
Lunch
Hal Helms: Object Oriented Modeling
I went to the wrong room, and wandered into this, but didn't want to move because I had access to an outlet. Additionally, I've always wanted to hear Hal Helms talk.
This was a theoretical/philosophical discussion on the way to architect object oriented code around your data model. It was a very cool introduction about talking about this stuff better. The whole getter and setter model isn't enough. Don't think about objects in terms of data you can get out of them... Think objects in terms of what they do.
Hal starts at the UI and works down to the database. I guess, but I'm not sure, is that you have to shift your mind to thinking of the database as just a persistence layer to save object state. You have to ask yourself "What does it mean to be a <blank>?"
Hal's Tiers of OO Applications
Data
Domain Model
Service Layer
Application Layer
A lot of this went over my through my fractured attention span. My brain is full.
But cool notes:
Favor composition over inheritance
Feel free to make mistakes
Separation of Concerns
High cohesion
Well defined purpose
It should do only what it should do
Low Coupling
Through API's instead of hard coded knowledge
Design Patterns
They arose over time
Collected wisdom of the development world.
He finished up with a good example of why Inheritance is not the best pattern to use in many, many cases.
Chris Scott: Introduction to Aspect Oriented Programming with ColdSpring
Aspect Oriented programming is a relatively new comer to the programming world. It complements OO and controls wide reaching concerns. Chris Scott started talking about why we do it, before talking about how.
Cross Cutting Concerns
Security
Transactions
Caching
Logging (Poster Child)
Two central themes
Interception
Grabbing method calls (Join Points)
Introduction
Add functionality before, after, and around methods
Doing so is called Advising
This was another one that blew my mind.
He showed us an example of caching that was so robust, he took the database of a database application down, and it still worked. He also showed a great example of a use of custom metadata in CFC's.
After this I was done. Chris Scott hurt my brain. This stuff was so cool and so powerful, I want to use it. I just don't know where yet.
The beds at the Sofitel almost made me miss my first session.
Matt Woodward: OO Architecture Back to Front
The focus of this session was developing OO architectures starting at the database and moving forward. Matt Woodward started with a quick overview of OO. One of the best things he explained was that all of the layers of an OO application serve to increase the coupling and decrease the cohesion of your application. He went over a few basic patterns like DAO, Gateways, Beans, etc, and a few layers like service, business, controller etc.
Interesting tips and pointers
You want to do multiple layers of validation.
Server side validation should probably live in the bean.
This was a really good presentation about the whys and wherefores of the multiple layer development style. He's going to post it up on his site. Definitely check it out if you get a chance. It would be a good tool to explain this stuff to others.
Steve Rittler: Using the Adobe Flex Toolkit for Apex
Steve Rittler's session wasn't announced. Being a fellow Philly ColdFusion guy, I figured I would give him some support. But it was so far outside my bailiwick that I figured I would be better served going to another session.
So I wandered into Adam Lehman's session.
Adam Lehman: Scorpio: Diagnostic Server Monitoring and Realtime Performance Alerts
Adam went over the server monitor, showing off what it could do.
He started with an overview of how this tool could be used in development. Since the server monitor shows how much memory all of your scopes are taking up, you can figure out the capacity of your application on your server. Very cool.
Cool Bites:
The server monitor has a force garbage collection button
Reports show the effectiveness of the query cache
You can see how the database connection pool is being used and queued
Configurable alerts so you can be notified if there are speed or responsiveness problems
Alerts can take snapshot dumps of the environment for troubleshooting after the fact
Configurable actions you can map to alert items. Like killing threads, or stop accepting requests
Multiserver monitoring panel will allow you to see status of all your ColdFusion servers at once
Sean Corfield: Real World SOA: Building Services With ColdSpring and Transfer
Despite persistent rumors that he was an impostor, Sean Corfield took the stage to talk about Real World SOA's. SOA's = API's is a good way to think about this stuff. Things have to be done differently. Sean went over these difference.
SOA is about more than services. You need to have clearly defined data. Basically you need to agree on the same semantics when you talk about data, and the same components. For the most part you really have to document these applications, and then actually make this information available.
Software as a Service (SaaS) is growing as a market at 20 per year. SOA's are the backbone of SaaS.
Separation of concerns is very important to be doing this type of application. The future of this space will be light application that call SOA's that don't have their own view or controller. These SOA's are all Model.
Tips:
Don't rely on client scopes
Session
Cookie
Client
In fact turn the session scope off in your application
Create some sort of token handling using a persistent store (database)
Remember that ColdFusion makes data easy to manage
Other technologies don't handle Queries
Keep data types simple
Typed structs are good
XML
You actually might need to use the This scope and <cfproperty>
Sean has made a Rest adapter, you can download at his site.
You don't want to just set access=Remote on your entire business layer.
Build a remote api instead
Might need to build API's for multiple technology
Unit Testing is necessary
Exceptions need to be handled differently
Fail gracefully
Return structured error message with fault indicator
Make sure that you throw codes along with text (because of internationalization.)
Clustering and Caching is a challenge
Tools to use:
ColdSpring
Manages the CFC's
Manages Transfer
Transfer
Manages the database
Handles all of the persistence of the application.
cfcUnit
Write tests
Automate tests
What worked well
Unit Testing
Managing the CFC's and database with ColdSpring and Transfer
Automated builds
Cruise Control
What went not so good
Using an old model for new work
Too many endpoints in the exposed API
Not enough unit testing
Lunch
Simeon Bateman: Fusebox the Original ColdFusion Framework
Simeon Bateman thinks that you should be using a framework, even your own. But he thinks that Fusebox is the best. I decided to go to this because some bad Fusebox code was what originally made me dislike Frameworks. Now that I've come around I figured I would give it another look.
Simeon took us from the beginning of Fusebox to the current day.
It was basically a good introduction to Fusebox. I had no interest in using Fusebox before this session; I now want to give it a try.
Break
I had a lull between sessions I wanted to attend. Evidently Jason Delmore's wife told him that I said I was annoyed with him yesterday. Poop. I didn't want to do that. I was mostly happy with what he had to say. There was much more positive than negative.
Additionally, Jason also helped saved someone's life yesterday, He was a total hero! He has that going for him.
Kelly Brown: JVM Server Tuning
I finished up the day with the very geeky JVM session with Kelly Brown. It was altered into a ColdFusion Performance Tuning session. I guess he extended it beyond where he initially intended it.
Concepts he went over:
Disk Based
Trusted Cache
Deleting saved class files
Finding them can be slower than compiling
Dependent on hardware and size of site
Memory based
A lot of these are tough because you control the number of items not size of memory footprint.
Maximum Number of cached template
Sweet spot
Too high - runn out of memory
Too low - performance issues
Maximun number of cached queries
Session and application scope
Session's can be wrecked by search engines so watch OnSessionStart
Mail and Charting can be cached too.
JVM tuning
You can change the memory footprint of the JVM
Jvm.config is where you can set a whole bunch of settings.
Change the JVM's JDK to improve performance.
Certified to 1.4.2_11.
Rumors of 1.4.2_13
Max Heap Size:
512mb default to low number of Gb depending on platform.
If you are seeing memory errors set this higher.
A lot of JVM settings will never need to be touched. Especially in CF 7.
You can check JVM through the java.lang.Runtime
Sun Virtual Garbage Collector tool.
Free download from SUN
Part of jvmstat
Processor Based
Simultaneous requests
His experience 15-20 per processor
Optimal depends on application.
Too high you spend more time switching out threads then processor
Too low, you don't get anything done.
Request Timeouts
Report and Charting threads
Jrun.xml
Edit away
But make a backup first.
Jrun Proxy Service
Connects Jrun to Webserver
Scheduler Service
Also allows thread manipulation
Load Testing
Final thoughts
Don't turn on debug in production
Update database drivers
Don't put client variables in registry.
All in all, today was another day that hurt my brain.
Jason Delmore delivered the keynote the really gave a good overview of the philosophy around Scorpio. Adam Lehman was evidently worried about Jason's lack of "marketingese" but I really liked him admitting that the use cases for things like <cfpresentation> and <cfreport> were hard to find.
New confirmed developments include <cfthread> and <cffeed>.
I was a little annoyed with Jason's response to my question. I asked "Is the Beta feature complete?" He gave me a hard time and cited the NDA. I could have just asked. "If I'm on the beta will you say anything new?" But I was trying to be nice.
Mark Mandel: Developing Applications with Transfer ORM
This was basically a good introduction to using Transfer. Mark Mandel did a really good job speaking. What I can't figure out is the main difference between Transfer and Reactor. I'm not saying there isn't one. I just wonder if there is anything that one does that the other doesn't do or vice versa.
If only I had access to Mark Mandel and ask him without being an ass about it. (Remember to ask before any receptions or parties tonight.)
Dean Saxe: Application Security and Compliance
Dean Saxe's presentation on security looked really promising. This is why I signed up for it. What I heard of it was good. However Sean's twitters about David Keith's session lured me out.
David Keith: Adobe.com
This was a great opportunity to find out how Adobe runs their site. They use a heavily tiered environment on both the hardware and application side. It validated what we do at Wharton a lot, which I was happy about.
They were also upfont about their weaknesses which was also very helpful. They talked about their single point of failure at the database level, and problems with colliding scheduled tasks.
Lunch
Sean Corfield: AJAX Integration With Scorpio!
Sean Corfield gave this talk despite the fact that he not an Adobe employee (and despite rumors that he was not in fact the real Sean Corfield.)
Interesting little trivia bit - AJAX came out of advancements cause by Outlook Web Access.
Cool features:
CFC Proxies in JavaScript, automatically
Yahoo UI controls
Databinding across controls
Rich Text textarea's
Auto Suggests
New Tags:
<cflayout>
<cftooltip>
At this point in the presentation Mark Drew started showing me his Project Unity stuff. Since I've seen a lot of what Sean was doing in the Beta, I paid attention to Mark Drew instead.
Adam Lehman: Scorpio: Working with .NET and Microsoft Exchange
Called the audible twice and decided to stay with what brought me to CF in the first place: Microsoft Exchange.
Adam spelled out the different ways that you can currently interact with .Net. Things like webservices, and various other types of wrappers. ColdFusion 8 will allow you to call .Net assemblies like CFC's or Java classes. Additionally it will perform better than all the other wrapper methods. On the backend ColdFusion creates proxies, much like webservices use skeleton objects on the backend.
He then went on to the Exchange technologies. Claim: ColdFusion Exchange tags can do anything that the Outlook Client can. Eh, not really, but it can do everything that you would want to build an application around. You can manipulate contacts, appointments, mail items, and tasks. You can't interact with say the Out Of Office message. "You can do anything to the objects CF exposes that you can do in Outlook" would be more accurate.
Interesting Ideas:
.Net interaction will allow CF to extend Sharepoint.
.Net interaction will allow CF to interact with IIS
Mark Drew: The CFEclipse Project
Mark Drew confirmed that he was never on the show 24. He then took as on an overview of the CFEclipse project.
Most of the people here are using CFEclipse, so he powered through the existing features. He spent a fair amount of time showing off Snippets which definitely are powerful.
Then he revealed Project Unity. Which I'm pretty sure is the killer application for CFEclpise. It's a CFFramework inspector that allows developers to basically interact with Frameworks through a variety of methods. One method looks a lot like the Component Explorer, but it also allows snippet like inserts of calls to Framework components.
What's really cool about it is that it understands the frameworks. So if you inspect a Fusebox project you can inspect individual circuits. If you inspect a Reactor project you can wire together relationships. In addition to viewing them, you can also edit them through a wizrd view that writes the code for you.
Finally it's full extensible, so if you have a framework, you can write your own XML to make it work with the CFframework explorer.
The key question is: When will it be released?
I figure I'll blog about the Birds of a Feather session after than tonight.
Well, festivities kicked off tonight with the registration and reception.
Nothing major happened, except that Dave and I confirmed once and for all that Mark Drew did not really hire Carlo Rota to narrate CFEclipse.tv. Hear that John P?
Squidhead is swimming along nicely. I've gotten some good suggestions, over the last few weeks, and figured I would post what's going on.
Dave Konopka, who works with me here at Wharton, has a pretty good complaint about Squidhead. Basically his complaint is that there needs to be another layer between the DAO and UI. We've taken to calling it the Business layer. Basically, many times his basic interaction with the database requires more than just one DAO operation, and often other operations not related to the database (logging, email, etc.) So to achieve perfect encapsulation and reusability through the application, he requires the business layer.
He provided me with a good bit of code for it, which will create Business beans for any of the DAO operations. Additionally it abstracts the whole "Is it an add or is it an update" logic, making the UI have to do less work.
I've added the business CFC creation routine to Squidhead and am working on rewiring the UI to use it. It will be optional, so that existing applications don't break, but it will be set to the default way of doing stuff.
Finally, I did get some requests for Fusebox integration, and MySQL compatibility. I'm working on those, but Dave's in my office, so he gets to sell me this stuff right to my face.
All the cool kids are doing it, so I figured I would share my cf.Objective schedule with the world. The twist is that I extracted it from my Outlook calendar using the new Exchange tags in Scorpio. I've included the code below.
Time
Session
Speaker
Thu 9:00 PM
Reception
Fri 8:00 AM
Breakfast
Fri 9:00 AM
Keynote -Top Secret Scorpio!
Jason Delmore
Fri 10:15 AM
Developing Applications with Transfer ORM
Mark Mandel
Fri 11:25 AM
Application Security and Compliance
Dean Saxe
Fri 12:30 PM
Lunch
Fri 1:30 PM
AJAX Integration With Scorpio!
Sean Corfield
Fri 2:40 PM
ColdFusion Flex Integration
Kevin Schmidt
Fri 4:10 PM
The CFEclipse Project
Mark Drew
Fri 7:00 PM
Birds of a Feather Sessions
Sat 8:00 AM
Breakfast
Sat 9:00 AM
OO Architecture Back to Front
Matt Woodward
Sat 10:15 AM
Using the Adobe Flex toolkit for Apex
Steve Rittler
Sat 11:25 AM
Object Think
Simon Horwith
Sat 12:30 PM
Lunch
Sat 1:30 PM
Fusebox - The original CF Framework
Simeon Bateman
Sat 4:10 PM
JVM Server Tuning
Nick Tunney
Sat 7:00 PM
Birds of a Feather Sessions
Sun 8:00 AM
Breakfast
Sun 9:00 AM
Keynote -Top Secret Scorpio!
Ben Forta
Sun 10:15 AM
Test-Driven Development with ColdFusion
Paul Kenney
Sun 11:25 AM
Understanding, Improving and Resolving Issues With Database Procedure Caches
Charlie Arehart
Sun 12:30 PM
Lunch
Sun 1:30 PM
Introduction to Cairngorm
Rob Gonda
Sun 2:40 PM
Introduction to Aspect Oriented Programing with ColdSpring
Chris Scott
Sun 4:10 PM
Leveraging ColdSpring to Build a Robust and Maintainable Architecture for Flex
It looks like with the Scorpio tour in full swing, the NDA is up on certain aspects of ColdFusion 8. (I'm still going to tread lightly though.) But according to this article from the downloadsquad, Adobe finally revealed that they went and added Exchange Integration to ColdFusion.
Up until now, the only game in town was using Webdav to communicate with Exchange. I've been pushing the little bit I know about it for the last year.
I've never been happier to be out of a line of work ever. This stuff is tough to write and fickle to maintain. Microsoft doesn't make it any easier by breaking stuff when they push out updates.
I've been working with it in the Beta tests and I can categorically say: Adobe has made it truly easy to interact with Exchange. Short of working in .Net, there is no easier way to programmatically interact with Exchange than with what the ColdFusion team achieved here. This is to say, having worked with .Net, there is no easier way to programmatically interact with Exchange than with ColdFusion 8.
I have some ideas for best practices of working with Exchange from ColdFusion when we can all talk more freely about it. In the meantime if you get a chance to get on the Beta trial give it a chance; it will knock your socks off.
April 25, 2007 Posted by Terrence Ryan at 10:50 AM
I figured I would blog about what I've been seeing during code reviews lately. Maybe someone else has been seeing too, or seeing other issues. I've omitted problems that deal with our shop's internal best practices, and tried to stick with things that would apply more globally. If I over applied something let me know. It's a long one, so more after the jump.
Make sure before doing this that the node is actually backed up. One or two messages in the queue does not a blockage make. But depending on the number of items and length of their stay, you can make the determination.
What this email reminded me to say was: DRY isn't just for code.
We had this problem a while back. Every once in awhile, the mail queues on a random one of our ColdFusion servers would back up. The mail would remain stuck until the server was restarted. Developers and users started getting pissed about their application email being delayed.
The short term solution was to check the queues every once in awhile. Once the problem stopped occurring, we stopped checking... until it happened again. We looked for a hotfix, to no avail. We did this a couple times, and each time we got burned when we stopped being vigilant.
Finally I said "Screw it; I'm scripting a solution to it." I started checking to see if files were in the spool directory of all of our servers. Then I had to make sure that the files had sat there for a little bit instead of just having been written there. Finally I had to send an alert with the needed fix.
No big deal, it's not advanced programming, it's not even particularly good code.
The point here is that it was running in a scheduled task... since I wrote it in 2005 (and restarted it earlier this year.) We had this problem again today, and nobody outside of my team noticed.
So what's the point of this besides a little bragging? Don't do things by hand that you can automate and forget about, or DRY isn't just for code.
It's been awhile, but I've finally got more to say about all this.
Backup
In the last one of these, I told you to back up your system. Maybe not directly, but it was there. Okay, so I didn't say it. I'm saying it now. Backup your machines. Do a tape backup, export to an external drive, do anything. Just backup your machines.
Backup Configuration Files Separately
Independent of a backup solution that takes care of your whole system, I would also recommend backing up configurations to separate location, in their current format. Meaning, don't put them on a tape, don't ship them off site. Just keep them somewhere you can access them. Why? Coldfusion is pretty light. CFML sites are comprised of pretty small files. Odds are, if you have a systems failure, it very well may be faster to rebuild a system from scratch then it will be to get a system backup restored and working. Rebuild your server, reinstall your webserver, and reinstall ColdFusion, all while getting the CFML files from backup. Then use configuration files you've stored elsewhere to restore both your webserver and Coldfusion to its old state. By this point, the CFML files should be out from a restore.
There are other uses for these files. You can use this method to clone your boxes, for clustering for example. Additionally, the ways they are broken up make it easy to share certain areas of configuration between machines. The most useful of these is neo-query.xml, which has all of your datasources on it.
Anyway, you probably want to know where all of these are:
ColdFusion configuration information is stored in xml files, in [CfusionRoot]\lib.
IIS XML configurations can be exported from the IIS Manager
Right Click website
Choose "All Tasks"
Choose "Save Configuration to file."
I'm sure that Apache has something to handle this too. But I don't have any experience with it.
Backup Certificates
If you are using SSL certificates, back them up. They are a pain in the ass to manage. If you lose one without a backup you have to depend on the Certificate Authority to get your SSL service back up. Better to just have them ready to go in case of a problem.
Again I can only speak authoritatively about IIS, but:
Go to IIS Manager
Right click your SSL secured site
Choose "Properties"
Go to "Directory Security"
Under "Secure Communication" hit the "View Certificate" button
Choose "Details" tab
At the bottom "Copy To File"
That will bring up the "Certificate Export Wizard." I usually choose the default options, with one exception. I choose "Yes export the private key." It's less secure, so you want to make sure you store them somewhere safe, but you'll be able to do this again with a certification created from a backup with the private key.
That's all I got this time around. Sorry it's all backup related. Nothing happened; I was just collating tips for building a new Coldfusion box in our environment, and realized that these were all pretty important to doing that
I was in a code review earlier last week, and someone said that they didn't like using <cftry> and <cfcatch>. When we as a group investigated further it was revealed that they had used it "incorrectly," experienced problems for doing so, and labeled the try catch model as bad, instead of the implementation. So I figured I would quickly go over my opinions of what you should be using them for.
To start with, the incorrect usage of <CFTry> was wrapping it around a troublesome page, so instead of visibly erroring, the page would just silently fail. To add insult to injury, there was an error in the cfcatch block which caused the whole thing to throw an application level error anyway. This was, to put it mildly, a flawed use of <cftry> and <cfcatch>.
In a nutshell, the <cftry> and <cfcatch> model in ColdFusion is for handling expected errors, as opposed to handling unexpected errors. ColdFusion has a pretty good system for handling unexpected errors - a combination of <cferror> tags, and use of onError in the application.cfc. So wrapping an entire page in <cftry> to catch any error that may come up is not only the wrong thing to do, it's also pretty redundant.
In my opinion <cftry> and <cfcatch> should be used to handle errors around small pieces of code that have the potential to error in predictable ways. For example here is a line of code from one of my applications:
In it you'll notice I'm doing a webservice call. In my experience webservices can have issues with the skeleton ColdFusion creates to consume them, especially if details about the webservice change. However, my application has little control over this webservice. So I wrap the call to the webservice in a <cftry> block, and if my expected error condition occurs, (something with to do the skeleton, or "stub objects") I reset the webservice and try again.
You'll notice that if it isn't a "stub objects" problem, it assumes that it is some other issue, and rethrows the error so the application error handlers can tackle the problem. Why, because it is an unexpected problem, not an expected one.
In conclusion, I'm not speaking for all programming languages, but at least in ColdFusion <cftry> and <cfcatch> should be used to handle error that you can predict. The shouldn't be your default error handling technique, and like a <Cflock> or a <cftransaction> they should surround as little code as possible.
This came up in a code review today. There were a couple misunderstandings about it, so I figured I would share the explanation publicly.
First, there are two types of whitespace what are in play here. Whitespace in your code for the purpose of properly formatting, and extra whitespace in your ultimate HTML output that comes from the various loops and other mysterious sources in ColdFusion. In simple terms, the first is good and the second is bad. However, you shouldn't try and get rid of the first in order to get rid of the second.
First, to see a demonstration of what I am talking about, go to Wharton Computing's Brainstorm. Once you're there, "View Source" from your browser. At the top of the page, you'll see a few lines of empty space before the DocType declaration. Select them with your cursor. You'll see they're not just page breaks, but spaces and tabs.
(I'm not picking on some random developer; I did both of these applications.)
That's the easiest way to show you what I'm talking about. That whitespace makes the output HTML page bigger, as each piece of whitespace is a character that you are sending to you user.
Well how much of a problem is that little bit of whitespace? Well frankly not much, but if you understand how it gets created, you realize it can become a very big deal.
It gets created in loops that, in the case of the WWT, are being called before the header is rendered. (It can happen anywhere in a page, but that's where it's happening in this application.) So in the case of the WWT a few loops are generating say 1 character of whitespace per iteration. But suppose for a moment that you were doing hundreds or thousands of iterations... In multiple loops... with multiple characters per iteration... in multiple included files.
Like everything in coding, it's not that one little thing is so bad, it's that the little bad things tend to aggregate together, form large bad things, gain sentience and run amuck!
Ray mentioned a whole bunch of techniques you can use to reduce whitespace, but he doesn't say what not to do to reduce it. (Awkward sentence, but bear with me.) You should not start formatting your source code to reduce the number of lines you use, the number of tabs, or the number of spaces. Readability of your code is still extremely important. Don't change your code formatting to fix your html formatting. Find the spots that generate the whitespace. Then utilize the techniques he mentions to treat the problem topically. (My favorite method is to insert the <yo /> tag randomly throughout the source.)
If you're not sure if you have this problem with your page, or if you're not sure how big an impact the whitespace is having, use the tools at Web Site Optimization to see how big your output page is. Alternately this can be accessed via the Firefox Web Developer Toolbar.
I have found reason 531 to be glad I switched to developing in CFEclipse. Its name is Jupiter. It's a code review tool for Eclipse. I find myself in complete disbelief, but I think I love a code review tool.
Why? What does do that makes me love it?
It links annotations directly to the code via line numbers.
Because of that linkage, you can open the code directly from the code comments.
It allows several levels of severity and categories of comments.
It allows for teams to collaborate on code reviews.
It saves notes in an easily parsed XML file for external reporting.
Dave and I are experimenting with it. It looks like it will make all of the code reviews we have to do a little easier.
I've done three updates to Squidhead since the last time I blogged about it. Two of them were pretty major so I figured I would squawk some more about it.
First, I haven't forgotten about adding support for other DBMS's other than Microsoft SQL. I haven't done it, but I have re-architected Squidhead slightly to make it a bit more possible to do so down the road. There's one more step I need to take to open that up, which is focusing on primary key's rather than identity. I know it should work, but I'm just not ready to pull the trigger on it.
Second, I've added quite a few features around the main unique feature of Squidhead, stored procedures. The whole focus of Squidhead is pulling in user created stored procedures and creating the ColdFusion code to support them. The recent changes I made allow Squidhead to properly handle store procedures that return multiple result sets. Alternately it can handle multiple output parameters, from the stored procedures.
Third, I've got a Build a Blog in 15 minutes presentation in the works. It's a respectful homage, to Joe Rinehart'sYouTube presentation on ModelGlue. I figure it's effective in getting the feature set across, and appropriate since Joe's presentation got me into code generation and frameworks in the first place.
Finally, I have a pretty good idea of what's coming down the pike for Squidhead. Before I add support for other DBMS, I'm going to try and flush out the feature set, so as to avoid writing multiple versions in tandem. I prefer to port over the full version to other databases. My current list of updates includes support for foreign and primary keys. I'm also looking to add some form validation. That being said, if anyone has any thoughts, I'm very open to them.
I had a problem this week due to recent updates for DST. LDAP over SSL stopped working. It took me a fair amount of time to track down the answer, so I figured I would share.
Basically, the secure certificates store is tied to the JVM, not to ColdFusion or even JRUN. So when you update the JVM you lose a bunch of Certificate Authorities in your keystore (I assume since the file is so much smaller) and you lose any custom Certificate Authorities you may have added.
I found the solution at via a Google search at sagewire.org (JVM upgrade breaks secure CFLDAP connections), but basically the solution is to copy your former copy of the cacerts files to the new JVM's location, then restart ColdFusion.
March 13, 2007 Posted by Terrence Ryan at 11:56 AM
I seem to remember reading this speculation somewhere else, but a quick Googling yielded nothing. I think that's a pretty decent sign that Adobe is targeting August for ColdFusion 8. Woohoo. Good news to those of us that want to deploy apps for a new school year.
Either that or they're screwing with us. If that is the case I say: "Shame on you, Tim Buntel. Shame."
I finally got around to listening to the ColdFusion Weekly Podcast on February 12th. Squidhead was mentioned - WoooHooo! Wait a minute from the description it seems like Squidhead just creates CRUD + list stored procedures. The key to my disappointment is the word "just." Squidhead doesn't just generate stored procedures. It also reads in stored procedures that you create. So sure, it scaffolds the basic CRUD and list actions building stored procedures and CFC's but also builds CFML from user defined stored procedures.
So for example, you have a table, person, with columns personid, username, password, first and last name. You run Squidhead once, you get the 4 CRUD procs, plus a DAO CFC to call them, then you get a list proc, plus a gateway CFC to call them. But then you go back and write a procedure "usp_person_select_by_username" because you would rather do that then select by identity. You run Squidhead again; it adds "select_by_username" function to the person DAO CFC.
But let's take it one step further, suppose you write a stored procedure named "usp_person_auth" that takes the username and password and checks them as an authentication routine. Run Squidhead again. You'll now have an "auth" function in your person gateway CFC.
The idea here is to do the database work in the database, and not have to do the manual work of writing the cfml calling code. Sure, it creates stored procedures, and that is a leg up, but it also lets those of us that like starting in the database an even higher leg up... (not sure if that's the right modification of that metaphor.)
Anyway, don't take this as a swipe at Matt and Peter. I'm glad to have some exposure in the ColdFusion Weekly Podcast. It's my bad that I haven't been publicizing Squidhead better.
Could someone please explain the differences between cfc package and public access? I thought that package access made the method available to other templates within the same application, but that doesn't seem to be the case.
Now, I remember being confused by this when I first started doing CFC's so figured I would share.
A function with an access of "package" will be restricted to calling CFC's and templates in the same directory as the CFC file of the function.
In my personal experience, I haven't found access=package to be terribly useful. I tend to organize my files into subfolders like cfc, and then further subdivide by type of CFC. (Gateway, DAO, utility.) So to access them, I tend to put functions as either public or private. All in all, "package" just makes it harder to work with all of this stuff.
However, I have the luxury of working on private server, and not a hosting provider for the majority of my work, so my view maybe atypical. Anybody have a different viewpoint?
February 28, 2007 Posted by Terrence Ryan at 5:22 PM
My wife, Janice, and I work for the same company. In fact we work for the same boss. It has its ups and downs. But if we didn't work together, situations like these would never happen:
Janice was working on a Perl script that handles integrating Active Directory and MajorDomo. It was buggy and confusing and overall not well written. Janice was struggling with the parts that were crappy, basically trying to grok the ungrokable, and she calls me over.
Janice: Can you tell me what this section of code does:
## Im not really sure why I did this. It works so back off!
my $max = $mesg->count;
for($i = 0 ; $i < $max ; $i++) {
my $entry = $mesg->entry($i);
foreach my $attr ($entry->attributes) {
$dn=$entry->get_value($attr) }
}
Me: No.
Janice: Why not?
Me: I didn't understand it when I wrote it. What makes you think I understand it now?
You see, I've worked for our current department on and off for the past 6 years. My first past through the group was doing Exchange and Windows Domain systems administration. I managed the upgrade from NT4 to Windows 2000 and Active Directory. I wrote the first batches of code that we used to integrate Active Directory and our legacy systems. That meant Perl. I learned it sort by accident back in the day, and at my height of ability I was never one of those guys who would write twenty lines of function in one line.
Which brings us back to this section of code; I wrote it in my first Active Directory LDAP Perl to CSO script. It was copy and pasted by another developer, and reused again. Until my wife had to deal with it... six years after I wrote it.
Sorry, hon.
February 27, 2007 Posted by Terrence Ryan at 9:48 PM
I've been meaning to blog about <cfntauthenticate> for awhile, but I keep forgetting. However, someone had an issue with it today, and it spurred me on.
Disclaimer
I don't work for Adobe, so I have no idea why they did anything they did. Any supposition posted here is just that my supposition. Additionally, it's not meant as criticism, as for the most part <cfntauthenticate> does exactly what it is supposed to do.
We're a Window shop that relies heavily on out Active Directory Domain. We use it for LDAP mail routing, Exchange, and single sign on across our environment. From time to time we've had issues with <cfntauthenticate> under certain outlier conditions. Let me take you through some of them.
Too Many Groups
Occasionally, we'll run in to singular users that cannot log into some applications but can log in to others. We'll tease out variations in form inputs, and ensure the username and password works, and still can't figure it out. We'll look at our logs that track the reason for failure, and we'll see "UserNotInDirFailure." Even turning on the throwError option of the tag doesn't help.
Eventually we trace it back to the listGroups flag. Turn it off, it succeeds, turn it on, it fails. So it's something with the groups. Try taking some groups away from the user. Voila it stops failing.
Turns out, there is some number, N, of groups over which some sort of uncaught error will start to be thrown. It gets caught by the default error code and gets thrown as "UserNotInDirFailure." N is a little nebulous, as it is unclear to me what effects domain local groups versus global groups versus distribution groups has on N. But in my last set of tests, N was 23.
To workaround, if you aren't using groups, don't use listGroups, as you don't need it. If you are using groups for let's say, authorization, revert to using LDAP for retrieving groups information. Also you could just prune your group membership...
Service Account Issues
This is the one that happened today. Every user's login was returning "UserNotInDirFailure," but only for a particular server. No changes in underlying networking were made.
My default recommendation: restart the server. When the admin of that server did that the ColdFusion service didn't start. A quick check of the system logs showed that the login for the account the ColdFusion service was running under was failing. Turns out someone changed the password of it and didn't change it in the services configuration on the server. It took about 36 hours before the problem was noticed.
According to the documentation, "ColdFusion must run as a user that has the privilege to authenticate other users in the specified domain." So problems with the service account would cause problems with the tag.
No workaround here, just manage your service accounts properly.
PDC emulator
Active Directory domain controllers are intended to be redundant. Except for something called Flexible Single Master Operations roles, or FSMO roles. Each FSMO role makes the domain controller that hosts it unique in a fashion. I'm not going to go into all of it, but suffice it to say one of those FSMO's is "PDC Emulator." PDC stands for Primary Domain Controller, and was a feature of NT 4 and below. Basically the PDC was the domain controller to which domain information was read from and written to. Other domain controllers only allowed read operations. When Microsoft moved to Active Directory and multiple domain controller model, they left the PDC Emulator role in order to provide backward compatibility with tools that used NT 4 API's for various operations.
What does all this have to do with ColdFusion? It's my theory that <cfntauthenticate> uses the vestigial NT 4 API's. I base this theory on the fact that if your PDC emulator is inaccessible, <cfntauthenticate> will fail for all users. However, if you have throwError set to false, you won't know what is going on you'll get a "UserNotInDirFailure" error. However, if you set throwError to true, you will see the real message, "Could not find domain controller for this domain XXXX" Where XXXX is the name of your domain.
There's not much you can do about this. If the PDC emulator is unreachable from your Coldfusion server, <cfntauthenticate> will not work. The only solution I have come up with to replace <cfntauthenticate> with an analogous CFC that uses Secure LDAP queries against the domain controller instead.
Conclusion
I blogged this because when I've gone looking for <cfntauthenticate> errors, I've only found my own random posts on CF-talk. Hopefully, someone else will be less mystified by errors with this very useful tag.
February 21, 2007 Posted by Terrence Ryan at 8:47 PM
I'm not talking about being unemotional about code, which would be "objectively". No, "objectly," I'm talking about code generation. When I first started writing Squidhead, I was writing procedural code to generate my code. After all, it's tempting to think of it procedurally, as code tends to read from top to bottom. One of the breakthroughs for me was figuring out that most of the coding structures I was using can be expressed as objects. I mean the actual code text itself can be expressed as objects. In ColdFusion, this means a CFC.
Let me show you an example of what I'm talking about: