Tuesday, November 11, 2003

Good bye blogger

I've finally done it! I moved my blog off blogger, it can now be found at petefreitag.com. The new RSS feed is http://www.petefreitag.com/rss/web/ (for a web development only feed) or http://www.petefreitag.com/rss/ for all categories.

Monday, November 03, 2003

DNS Stuff

Here's a handy site for system administrators, and other such people: dnsstuff.com. It has several web based dns and ip lookup tools. One handy one is the ISP cached dns lookup. This is handy for testing round robin dns, and also to see when your dns changes take effect, here's a lookup of www.yahoo.com they are using round robin dns (different ISP's are getting different IP's to goto).

Monday, October 27, 2003

ColdFusion Code Review Tool now $50

I lowered the price on our ColdFusion CodeReview tool today to $50 (from $200 per developer)! The tool can find problems in your code (such as lack of CFQUERYPARAM, or SELECT *), and you can also easily define your own rules in just a few lines of code.

Even if your not interested in the tool, don't forget that the code review rules are posted on our web site - free for everyone to use.

Thursday, October 23, 2003

Top 3 differences between PostgreSQL and MS SQL

I recently switched a database server from MS SQL Server over to postgresql. Here's the top three differences in SQL:

  • NO TOP, so SELECT TOP 10 * FROM table, becomes SELECT * FROM table LIMIT 10 you can also use the maxrows attribute of CFQUERY to do this, if you want cross db code (which is good). MySQL also uses the LIMIT sytax, but Oracle uses yet another syntax
  • LIKE statements are case sensitive in postgresql, they can be made case insensitive like this: SELECT * FROM table WHERE LOWER(column) LIKE '%#LCase(var)#%'
  • The plus operator cannot be used for concatination so SELECT firstname + ' ' + lastname AS fullname becomes SELECT firstname || ' ' || lastname AS fullname this way works on both servers.

Amazon's Search inside the book

Amazon is now offering full text book searching, they call "Search inside the book".
Starting today you can find books at Amazon.com based on every word inside them, not just the author, or title keywords. Search inside the book -- the name of this new feature -- searches the complete inside text of more than 120,000 books -- all 33 million pages...

And while we are on the subject of Amazon, check out this Shopping web site for findind deals on Amazon.com. There is also a shopping blog that goes with it.

Wednesday, October 15, 2003

ColdFusion Training

I recently learned of two resources for developers looking to improve their ColdFusion skills:

Webucator (http://www.webucator.com) - Webucator provides customized onsite ColdFusion training an At-Your-Own-Pace online ColdFusion courses.

LearnByHeart (http://www.learnbyheart.com) - LearnByHeart is a Web-based service that helps developers pass Macromedia certification exams by practicing on sample exams.

What Every Software Developer Must Know About Unicode and Character Sets

Joel Spolsky has a good article titled: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).

Monday, October 13, 2003

HackNotes for Linux and Unix

There is a review of HackNotes Linux and Unix Security portable reference on slashdot. Looks like a pretty good book, I know that the CodeNotes series are good concise references. They are typically under 250 pages (this one is 224 pages) which is nice when many books web developers are buying are thousands of pages.

I have CodeNotes for J2EE, CodeNotes for Java, CodeNotes for ASP.NET, and CodeNotes for XML. I have found all of them to be pretty good, the J2EE one has been most useful to me, and the Java one is good, but I know Java pretty well so I don't have much need for it. The books are also dirt cheap, so you can't go wrong.

Wednesday, October 01, 2003

Using Ant to test Concurrency

Apache Ant is an awesome tool for creating batch builds, and doing all sorts of automated tasks. It was designed to replace make files, but you can use it for lots of things, as my example will show. Ant uses an XML language, with tasks (tags) to compile java classes, run java classes, manipulate the file system, create zip or tar.gz files, run SQL statements, XSL, FTP, etc. It also has an extensible API so there are tasks to do pretty much anything you would like to automate. We use ant at CFDEV to package our products into zip files, encrypt CFM templates, create multiple versions, and even upload the distribution files to our server - all in one step!

To get started check out the Ant Manual

One Ant task that I have found useful recently for testing concurrency is that parallel task. It allows you to run several ant tasks within their own thread. I was using this to test some java code but you could also use it to test a web site.

Here's a code sample testing concurrent requests.

<?xml version='1.0'?>
<project name="Concurrent" default="test" basedir=".">
	<target name="test">
			<get src="http://www.macromedia.com/" dest="1.html" />
			<get src="http://www.macromedia.com/" dest="2.html" />
			<get src="http://www.macromedia.com/" dest="3.html" />
			<get src="http://www.macromedia.com/" dest="4.html" />
			<get src="http://www.macromedia.com/" dest="5.html" />

Save the above contents in a file called build.xml and run the file by browsing the directory you saved it in with your shell, and typing ant (after installing ant ofcourse). You can add more concurrent threads just by adding more get tags.

Friday, September 12, 2003

Parsing RSS with CFMX

I came up with a code sample to parse RSS with CFMX today based on a question about CFMX XML functions on my local CFUG mailing list. It should do ok with RSS 2.0, and 0.91, and also well formed RSS 0.92. It won't work with RSS 1.0.

Tuesday, September 09, 2003

Open Up RDS

A recent thread on CF-Talk asked if anyone had documentation for the RDS protocol, or if anyone had tried to crack it. RDS works over http, so its possible to just use a protocol analizer to capture the communication between CF Studio, or Dreamweaver and the ColdFusion server. While that is possible, the best solution would be for Macromedia to simply document how it works. I suggest that you send in a request to the ColdFusion wish form

I use RDS a lot, and you can use it securly if you use it over SSL. I would like to be able to connect to RDS from a Linux desktop, as well as from other IDE's such as JEdit, and Eclipse.

Friday, September 05, 2003

PostgreSQL and ColdFusion

Jochem van Dieten has a good resource on the PostgreSQL for ColdFusion developers. It has things such as queries to list tables, DDL for creating client varaible storage tables, and other tips and tricks. Check it out if you haven't played with PostgreSQL or even if you have.

Thursday, August 28, 2003


Here's an idea for a new tag in ColdFusion, CFYEILD. Consider a web site that receives a several concurrent requests. ColdFusion will create N threads to process the requests, if there are more than N concurrent requests, they sit in a queue.

The java thread object has a method called yeild() which when called allows other threads to run, it's kind of a way of saying, if anyone else want's to cut in front of me and take the processor go ahead. On unix the nice command allows you to lower the priority of a process.

What I'm getting at would be a way for a CFM file or application to tell the app server that, I'm not important, or perhaps, I am important. Perhaps you would say your main pages should have highest priority, while other pages may be queued longer.

Just throwing out an idea, not much of a priority for me, but perhaps some people would find it useful. I'd much rather see a CFIMAP in the next version of CF (BlueDragon already has a CFIMAP tag).

Wednesday, August 27, 2003

A Good, Free Log File analysis tool - awstats

There are a lot of free http log file analysis tools out there that haven't been updated since the mid 90's, awstats however is both free, and up to date. It looks a bit like web trends (though I haven't used web trends in several years). Here's an online demo. awstats can be used on several web servers including IIS, and Apache. You can either have generate static html files, or run with a perl script in the cgi-bin.

Here's a quick rundown of setting it up on unix/apache

Each virtual web site you want to track stats for should have a file /etc/awstats.sitename.conf the directives for the configuration file can be found here: http://awstats.sourceforge.net/docs/awstats_config.html they also provide a default conf file in cgi-bin/awstats.model.conf you can use this as a base.

Make sure your log files are using NCSA combined format, this is usually done in apache by saying CustomLog /logs/access.log combined you can use other formats but you have to customize the conf file.

You will probably want to edit the LogFile directive to point to where your logfile is stored, SiteDomain this is the main domain for the site, HostAliases lets you put in other domains for the site, and the DirData directive lets you specify where the awstats databases will be stored (each site will have its own file in the directory).

Once that is setup you will want to update the database this is done from the command line by running

perl awstats.pl –config=sitename –update 

Now copy everything in the wwwroot folder to a web root, and visit http://sitename.com/cgi-bin/awstats.pl if you want to view other domains use /cgi-bin/awstats.pl?config=othersitename

Where sitename would be the name of your config file awstats.sitename.conf

If you want to generate static html files run the awstats_buildstaticpages.pl script found in the tools folder. You have to give it the path to the awstats.pl perl script, and a directory to put the static html files in.

perl awstats_buildstaticpages.pl -config=sitename -awstatsprog=/web/cgi-bin/awstats.pl 

More setup info can be found here: http://awstats.sourceforge.net/docs/index.html

Moving SSL Certs from IIS to Apache

I found some instructions for converting SSL certificates generated for IIS to private key, and cert files you can use on unix, or Apache for windows.

First Export your IIS certificate into a pfx file (this is something you should do anyways for backup)

  • Run mmc.exe
  • Click the 'Console' menu and then click 'Add/Remove Snap-in'.
  • Click the 'Add' button and then choose the 'certificates' snap-in and click on 'Add'.
  • Select 'Computer Account' then click 'Next'.
  • Select 'Local Computer' and then click 'OK'.
  • Click 'Close' and then click 'OK'.
  • Expand the menu for 'Certificates' and click on the 'Personal' folder.
  • Right click on the certificate that you want to export and select 'All tasks' -> 'Export'.
  • A wizard will appear. Make sure you check the box to include the private key and continue through with this wizard until you have a .PFX file.
Next run openssl to extract the private key, and the cert file.
# Export the private key file from the pfx file
openssl pkcs12 -in filename.pfx -nocerts -out key.pem
# Export the certificate file from the pfx file
openssl pkcs12 -in filename.pfx -clcerts -nokeys -out cert.pem
# This removes the passphrase from the private key so Apache won't
# prompt you for your passphase when it starts
openssl rsa -in key.pem -out server.key

Wednesday, August 20, 2003

MyIE2 - IE Based fast web browser

MyIE2 released a new version of their web browser this week. I downloaded it today, and I'm quite impressed. MyIE2 uses MS IE to render and display content so everything that works in IE, works the same in MyIE. MyIE has a much smaller memory footprint than MSIE. I ran a quick test by visiting 3 web sites in both web browsers and recording the memory usage. MSIE was using 24MB of ram, while MyIE2 only used 8. In addition to being faster than MSIE it also has more features:

  • Tabbed Browsing
  • Support for IE Plugins (like the google toolbar)
  • Popup blocking
  • Ad blocking
  • Whois queries
  • Translation
  • Skinnable

It's a 1.7mb free download

Tuesday, August 19, 2003

SoBig - SoAnnoying

I was receiving the SoBig virus at a rate of over one message per minute today. Most of them were sent to pfreitag@cfdev.com I disabled this account today so I could get some work done. I am *not* going to enable that address again once the virus subsides, I mainly get spam and viruses sent to that address. So if you need to contact me use my primary address: pete at the domain cfdev with the .com top level domain (try and figure that one out spam harvesters!).

The Google API - CFX_Google

When the google api (an web service to use google's services) came out last year, I wrote a Java CFX tag called CFX_Google avaliable for free download with source code from cfdev. The CFX tag supports searches, and spell check, and returns results in a query object, there is an example and documentation.

Jason Dowdel asked me today if the tag was up to date. Our zip file includes the googlelib.jar file dated May 2002, the latest google api contains a googlelib.jar file dated Aug 2002. You should be able to replace the googlelib.jar file we provide with the latest jar from google without problem. I will update the zip on our site when I have a chance.

Monday, August 18, 2003

Real World Linux Security

Linux Security I read part of Real World Linux Security this weekend. It's a very detailed book that covers a wide range of security topics, from an author with lots of security experience. Some of the topics include adaptive firewalls (that log and block out intruders), how to be prepared in the event that a breach does occur, how to find Trojan's that may have been left after an attack, how to setup a fairly secure online ordering system that stores credit card numbers, and so on. From Amazon:

A hands-on guide to protecting Linux data from security risks. Introduces readers to the seven deadly sins of Linux security, showing how to set up firewalls, break in case studies, block spam, develop internal security policies, and recover from an intrusion quickly.

Thursday, August 14, 2003

Cross Platform Techniques

The post I lost earlier today due to the power outage had a simple way of checking to see if your on a unix OS at runtime, and also some tips for writing cross platform coldfusion.

<cfset isUnix = Left(cgi.cf_template_path, 1) IS "/">

<cfset pathSeperator = "\">
<cfif isUnix><cfset pathSeperator = "/"></cfif>

Running UNIX: #YesNoFormat(isUnix)# <br />
Path Seperator: #pathSeperator#

The first line check to see if we are running unix by checking the first character of a path, if it begins with a /, then we are running unix. You can also do something like this isUnix = server.os.name IS "UNIX" to set that variable, but I think my method may be a nudge faster because it doesn't deal with a synchronized scope (server scope), and it's checking a smaller string.

The next two lines find the path seperator using the same techinique, there are several ways of doing this as well, you can use the java System properties hashtable for instance. It should be pointed out that CFFILE and CFDIRECTORY will accept front slashes on windows, so one option is to just always use / to keep your apps cross platform, this can create messy paths sometimes however..

It is not very difficult to write cross platform applications in CFML as long as your aware of the differences on windows and unix, here are some of the common gotcha's

  • Application.cfm - Application.cfm must have the exact case I'm using here.
  • OnRequestEnd.cfm - Also must have the case I'm using here.
  • CFINCLUDE Template Case - The template path in your CFINCLUDES is case sensitive on unix, you can use my coldfusion code review tool to find templates with incorrect case, as well as missing templates. It will also check the case on your Application.cfm and OnRequestEnd.cfm files in addition.
  • Links, Images case sensitive - All paths to links, images, stylesheets, must be case sensitive as well, there is a workaround for this one however. If you install mod_speling in apache it will redirect the client to the proper page. This may not work all that well for images, stylesheets, or form posts however.
  • CFEXECUTE - CFEXECUTE will still work on unix but the applications your executing may not.
  • COM - not supported on unix.

So those are the main issues in porting a windows CF app to unix, the main thing to remember is case sensitivity.

got power?

I just got my power back about an hour ago (I'm in Syracuse NY). I was in the middle of posting a long blog entry when we lost our internet connection this afternoon, and I lost the entire post when I submitted it, I'll rewrite it later... Our office still had power when I left, but as I biked (I cycle to work whenever I can) out of the city, I could see street lights out, there was a bad accident in one of the intersections too. I was able to bike right through, but cars had to be detoured. I can imagine its much crazier in NYC though!

Wednesday, August 13, 2003

Search Engine Safe URL's in Apache 2

I've figured out an easy way to employ search engine safe url's on unix and apache2. It has always been possible to implement them with mod_rewrite, but its difficult to do globally for url's like this: www.site.com/page.cfm/id/4

Here's the script

<cfif NOT Find(".", cgi.path_translated)>
	<cfset webroot = GetPageContext().GetServletContext().getRealPath("/")>
	<cfset query_string = RemoveChars(cgi.path_translated, 1, Len(webroot))>
	<cfset urlArray = ListToArray(query_string, "/")>
	<cfset urlArrayLen = ArrayLen(URLArray) - 1>
	<cfloop index="i" from="1" to="#urlArrayLen#" step="2">
		<cfset url[urlArray[i]] = urlArray[i + 1]>

So you just need to include that in your Application.cfm, or in pages that need to use search engine safe url variables. NOTE that I'm pretty sure this will only work on Apache 2, and may need some tweaking to get it to work on windows with apache (probably just have to make sure the paths use /). This was tested on Apache 2.0.46 on Redhat9, it also works in a multi-homed environment (virtual hosts). One thing it will ignore are query string's with dot's in them.

I will write up an article explaining how this works when I have more time, but for now enjoy the code.

Tuesday, August 12, 2003

Google Calculator
To use Google's built-in calculator function, simply enter the expression you'd like evaluated in the search box and hit the Enter key or click the Google Search button. The calculator can evaluate mathematical expressions involving basic arithmetic (5+2*2 or 2^20), more complicated math (sine(30 degrees) or e^(i pi)+1), units of measure and conversions (100 miles in kilometers or 160 pounds * 4000 feet in Calories), and physical constants (1 a.u./c or G*mass of earth/radius of earth^2). You can also experiment with other numbering systems, including hexadecimal and binary.

That's quite a handy feature, but I was dissapointed to see that it cannot solve simple algebra problems such as: x+5=10. Still very clever on google's part.

Worm's a comin'

Feel's like a storm is brewing, I've gotten a few emails today from various security lists about the W32/Blaster worm. This worm effects Windows NT 4, 2000, 2003, and XP, here's the info from M$. Block ports 135, 139 and 445 (RPC DCOM) in your firewall.

By the way here are few security mailing lists you should be on if you run windows and or you have a computer connected to the internet:

Thursday, August 07, 2003

Searching without Verity

Sometimes you need to search a database query without using verity. In general Verity should be used when possible, because it will yeild much better results, at better performance than the solution I'm about to show. But there are reasons for not using verity, for instance compatibility with BlueDragon, a highly customized search query, or a shared host that doesn't allow it.

Single keyword searches are easy using the LIKE operator in SQL WHERE column LIKE '%something%'. If you need to search using multiple keywords, its a harder. Here's an exmple

 SELECT stuff FROM table
 WHERE column LIKE '%#Replace(Trim(q), " ", "%' OR column  LIKE '%", "ALL")#%'

Here column would be the database field your searching and q would be your search string. Basically that code replaces all spaces with:

%' OR column like '%

So if your search string is "Monday Tuesday" the resulting query would be:

WHERE column LIKE '%Monday%' OR column LIKE '%Tuesday%'

You can ofcourse easily replace the OR with an AND, or use a variable.

Tuesday, August 05, 2003

Classpath Migration Issue in CFMX 6.1

I Installed CFMX 6.1 on our live server today, and found that my Java classpath settings had been screwed up during the migration process. All the slashes were missing in the path, so a path like c:\java\activmail.jar would show up as c:javaactivmail.jar in 6.1.

The server in question was running Win2k, which had been upgraded from CF5 - CFMX - Updater 3 - CFMX 6.1 in its lifetime. Just keep an eye out for it after you install, and backup your settings before upgrading.

Rob Brooks-Bilison had already run into this. The solution is to use front slashes. So if you have set any custom classpaths in CFMX on windows convert the slashes to forward slashes before upgrading.

Another Update
Debbie Dickerson pointed out on the CF-Talk mailinglist that this is in the CFMX 6.1 known issues document. Issue 53031

Updating ColdFusion Studio / Homesite for CFMX 6.1

If your going to apply the Homesite CFStudio Tag Updater for CFMX 6.1 make sure you first apply the CFMX 6.0 tag updater it doesn't appear that the 6.1 updater is cumulative.

CFML Language History

Macromedia's web site is going to be busy today, lots of new stuff on there today. They released a CFML Language history document, that details the changes since CF 4.01. That is handy for me because I usually have to write CFML code that runs on multiple versions. I'm sure many consultants, and free lancers work with several different servers as well. Hopefully this will be integrated into the live docs soon.

Dan G. Switzer, II pointed this out on the cfguru list, thanks!

RedSky at Night Sailors Delight!

Macromedia Released ColdFusion 6.1 early this morning (code named RedSky). I'm really impressed with it, and I will be updating our server with it today.

Several people have posted blog entries about it already.

  • Dan G. Switzer, II keep a list of all related articles
  • Sean Corfield has several posts including DevNet articles, and info about the new LiveDocs site (which his team worked on, good job)

Friday, August 01, 2003

Interim RSS Feed

I have a RSS feed for this blog again - you can use it until I move the blog somewhere else: http://www.wcc.vccs.edu/services/rssify/rssify.php?url=http%3A%2F%2Fcfm.blogspot.com

Wednesday, July 30, 2003

Validating HTML/XHTML behind a firewall

Someone asked the question on the evolt mailing list about validating XHTML behind a firewall. The most popular way to validate XHTML is using the w3c HTML validator, however the only options are to enter a url, or to upload a file. That can be cumbersome, so steve clay wrote a handy php script that crawls a url and uploads the file then displays the results. I ported his script to ColdFusion below. It works great in CFMX, but there are issues in CF5 (cfhttp is url encoding the charset). You might also want to wrap a html tags around this code.

Ported To ColdFusion by Pete Freitag www.cfdev.com
Based on http://mrclay.org/junk/software/private_validator
License: (GPL) http://www.opensource.org/licenses/gpl-license.html 
<form action="#CGI.SCRIPT_NAME#" method="post">
	<label for="location">Validate Local URL:</label>
	<input type="text" name="location" value="http://#CGI.SERVER_NAME#/" />
	<input type="submit" value="Validate" />

<cfif IsDefined("form.location")>
	<cfset tempFile = GetTempFile(GetTempDirectory(), "validatorFile")>
	<cfhttp url="#form.location#" method="get" path="#GetTempDirectory()#"
		file="#GetFileFromPath(tempFile)#" />
	<cfhttp url="http://validator.w3.org/check" method="post" resolveurl="yes">
		<cfhttpparam type="formfield" name="charset" value="UTF-8">
		<cfhttpparam type="formfield" name="doctype" value="Inline">
		<cfhttpparam type="formfield" name="ss" value="1"> 
		<cfhttpparam type="formfield" name="verbose" value="1">
		<cfhttpparam type="file" file="#tempFile#" name="uploaded_file">
	<cffile action="delete" file="#tempFile#">
Query of Query in CF5 bug

If you are doing a QofQ's in CF5 with an ORDER BY, the columns in the order by statement must be in the SELECT statement, otherwise it throws an exception. So if you have a column that your only using for sorting you must add it to the select statement, even if you don't need it in the resulting query.

This bug does not exist in CFMX thankfully, I found it while testing an application developed with CFMX in CF5.

Wednesday, July 23, 2003

New products at CFDEV

We have two new products at cfdev, one has already been released, the other is in beta.

The first is a spell checker for flash text boxes, it was released a few weeks ago.

The second product, which I have been working on for the past few months is a ColdFusion Code Review tool. It is a ColdFusion application that runs through your code and finds security, performance, accessibility, and other issues and then generates a report. Each rule has a document online (that anyone can use) that explains how and why to fix the issue. Check those out here: http://www.cfdev.com/codereview/browse.cfm there are over 30 rules currently, and you can easily write your own (4 lines of CFML code).


I haven't had an RSS feed for a while now, I'm still figuring out what I want to do about it. The most probable action will be to setup my own site. I was going to upgrade to blogger pro, but you can't buy it now for some reason, their site has said check back in a week for the last 3 months.

We do incidentially now have a RSS feed for the news section on cfdev. It's RSS 2.0.

Wednesday, July 16, 2003

Thursday, June 19, 2003

Iterating over an Enumeration with CFMX

I tried writing some CFML code to iterate over a java.util.Enumeration, a fairly common thing to do in java, but was plagued with java.lang.IllegalAccessException's.

IllegalAccess exceptions usually occurr when you try to call a method using reflection (which CFMX does) that doesn't exist. However I'm quite sure that hasMoreElements() is a method of java.util.Enumeration. In fact if I cfdump the propNames variable the hasMoreElements method shows up! Here's the code I'm using:

<cfset system = CreateObject("java", "java.lang.System")>
<!--- properties is a java.util.Properties object --->
<cfset properties = system.getProperties()>

<!--- propNames is a java.util.Enumeration --->
<cfset propNames = properties.propertyNames()>

 <cfloop condition="propNames.hasMoreElements()">
	<cfset propName = propNames.nextElement()>
	#propName# = #system.getProperty(propName)#<br />

I suspect the problem has something to do with CFMX not realizing that propNames is an Enumeration, I wish that JavaCast accepted more types besides the primitives.

Here's the stack trace I'm receiving, I'm using CFMX U3:

	at java.lang.reflect.Method.invoke(Native Method)
	at coldfusion.runtime.StructBean.invoke(Unknown Source)
	at coldfusion.runtime.CfJspPage._invoke(Unknown Source)
	at Statement12.evaluate(Unknown Source)
	at coldfusion.runtime.CFPage.evaluateCondition(Unknown Source)
	at cftesta2ecfm779424527.runPage(C:\web\testa.cfm:19)
	at coldfusion.runtime.CfJspPage.invoke(Unknown Source)
	at coldfusion.tagext.lang.IncludeTag.doStartTag(Unknown Source)
	at coldfusion.filter.CfincludeFilter.invoke(Unknown Source)
	at coldfusion.filter.ApplicationFilter.invoke(Unknown Source)
	at coldfusion.filter.PathFilter.invoke(Unknown Source)
	at coldfusion.filter.LicenseFilter.invoke(Unknown Source)
	at coldfusion.filter.ExceptionFilter.invoke(Unknown Source)
	at coldfusion.filter.BrowserDebugFilter.invoke(Unknown Source)
	at coldfusion.filter.ClientScopePersistenceFilter.invoke(Unknown Source)
	at coldfusion.filter.BrowserFilter.invoke(Unknown Source)
	at coldfusion.filter.GlobalsFilter.invoke(Unknown Source)
	at coldfusion.filter.DatasourceFilter.invoke(Unknown Source)
	at coldfusion.CfmServlet.service(Unknown Source)
	at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:91)
	at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
	at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:226)
	at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:527)
	at jrun.servlet.http.WebService.invokeRunnable(WebService.java:172)
	at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:348)
	at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:451)
	at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:294)
	at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

I may end up reporting this one to Macromedia as a bug, unless I'm missing something here.

GetTempDirectory() returns a different path in MX

I noticed today that GetTempDirectory() returns a different path than it did in CF5 and prior versions. In CFMX it returns cfusionmx/runtime/servers/default/SERVER-INF/temp/wwwroot-tmp.

I'm not quite sure why this is, because the java System property java.io.tmpdir = C:\WINNT\TEMP\ on my machine. I would have thought they would use that value as CF5 does.

Anyways I thought it should be pointed out since it is not in the release notes. I'm not going to report it as a bug, because I don't think it makes much difference what directory GetTempDirectory() returns as long as its a temp dir.

Wednesday, June 18, 2003

Query of Queries with maxrows bug

I found a bug today in CFMX, CF5 executes the code as you would expect.

Essentially if you do a query of query with maxrows, and then do another q of q on that result, the resulting q of q is using the wrong query and returns the wrong number of rows.

<!--- make a query --->
<cfset q = QueryNew("a,b")>
<cfset r = QueryAddRow(q)>
<cfset QuerySetCell(q, "a", "a1", r)>
<cfset QuerySetCell(q, "b", "b2", r)>
<cfset r = QueryAddRow(q)>
<cfset QuerySetCell(q, "a", "a2", r)>
<cfset QuerySetCell(q, "b", "b3", r)>
<cfset r = QueryAddRow(q)>
<cfset QuerySetCell(q, "a", "a3", r)>
<cfset QuerySetCell(q, "b", "b1", r)>

<!--- dump it, 3 rows --->
<cfdump var="#q#">

<!--- select max rows of 2, 2 rows --->
<cfquery dbtype="query" name="result" maxrows="2">

<cfdump var="#result#">

<!--- select everything from the 2 row query returns 3 rows? --->
<cfquery dbtype="query" name="result2">
	SELECT * FROM result

<cfdump var="#result2#" label="this should only have 2 rows, but it has 3">

I reported this to Macromedia, and they verified it as a bug.

Tuesday, June 17, 2003

Using UUID's for CFTOKEN and Database client storage

Just a heads up if your using UUID's for CFTOKEN values with database client storage when upgrading to CFMX, be sure to change the size of the cfid field in the CDATA and CGLOBAL tables. The cfid field stores both the cfid and cftoken value as follows cfid:cftoken. The cfid is usually around 7 characters, and the cftoken when using a UUID is a 35 character UUID plus a 17 character prefix. Just to be safe I changed the size to 64 characters, and changed it to a varchar type.

Below is the error message generated:

Operation failed on the data source named "yourdatasource". 

Reason of failure "[Macromedia][SQLServer JDBC Driver][SQLServer]String or 
  binary data would be truncated."
Stack Trace:

        Operation failed on the data source named "datasourcename".
        at coldfusion.runtime.JDBCHelper.Store(Unknown Source)
        at coldfusion.runtime.ClientScopeServiceImpl.PersistClientVariables(Unknown Source)
        at coldfusion.runtime.ClientScope.commitChanges(Unknown Source)
        at coldfusion.filter.ClientScopePersistenceFilter.invoke(Unknown Source)
        at coldfusion.filter.BrowserFilter.invoke(Unknown Source)
        at coldfusion.filter.GlobalsFilter.invoke(Unknown Source)
        at coldfusion.filter.DatasourceFilter.invoke(Unknown Source)
        at coldfusion.CfmServlet.service(Unknown Source)
        at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:91)
        at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
        at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:226)
        at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:527)
        at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:198)
        at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:348)
        at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:451)
        at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:294)
        at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

Tuesday, June 10, 2003

Patterns Central

This web site: Patterns Central was pointed out to me today by a coworker. It has articles, and forums about design patterns.

Wednesday, June 04, 2003

Compiling the CFMX Apache Module from source code

I put up a howto on cfdev for installing the ColdFusion MX Apache module from source on linux, as well as a howto for installing Apache 2.0.46 from source, and a howto get php working on Apache2. To compile the apache module you need to install Apache from source, the RPM installation I had didn't include the apxs tool which compiles the module.

Friday, May 30, 2003

Customizing Debugging Output

In ColdFusion MX you can customize the debugging output by editing or adding files to the wwwroot/WEB-INF/debug directory. I modified the dockable.cfm file so the window with debugging information would not pop up automatically by commenting out line 229. You can also add your own file to the directory and it will show up in the CF administrator as a debugging type.


Nathan adds the following:

I modified the classic debugger a while ago to cfdump the queries. It's proven to be a great addition to my arsenal. Here's how: classic.cfm, line 438, after the line with cfdebug_queries.body, add this:

<cfif CFDEBUG_QUERIES.result[currentrow].recordcount LT 500>
   <cfdump var="#CFDEBUG_QUERIES.result[currentrow]#" label="Results For  #cfdebug_queries.name#" />
   Too many results to print

I moved this from the comments section to the post because its much easier to read here.

Tuesday, May 27, 2003

Go to MIT for Free

MIT is publishing course material online at its MIT Open Courseware web site. One relevant course is the Laboratory in Software Engineering. The good stuff is under Lecture Notes where you can find PDF documents containing the lectures (including design patterns, case studies, and the concepts/fundamentals of Software Engineering). These aren't outlines, they read like a book almost. You can find a complete list of courses here.

I'm Back

I've been out of town quite a bit this month, thus the absence of posts. In the beginning of the month I was at the ColdFusion Cruise-n-Learn, it was a great time - I look forward to the next one (word has it that it will be leaving from the west cost, and possibly going to Alaska). Feedback from this cruise was great, the attendies actually did learn a lot, and it wasn't just a week of vacation so tell your boss, and sign up next year.

I was also hiking Mt. Marcy this weekend, which has nothing to do with ColdFusion, but it concluded my excersions this month. So I'll be back to normal for a while I think.

Wednesday, April 30, 2003

Clustered JDBC

Here's an open source project that CFMX and J2EE developers will find interesting: c-jdbc which stands for Clustered JDBC. It's basically a JDBC driver that lets you cluster several databases (any db with a JDBC driver pretty much), you can even have a cluster of different types of databases that operate on the same schema (eg Oracle and PostgreSQL).

The concept is called RAIDb (Redundant array of inexpensive databases), and they define several types of RAIDb levels:

  • SingleDB: load balancer for a single database backend instance.
  • RAIDb-0: full database partitioning (no table can be replicated) with an optional policy specifying where new tables are created.
  • RAIDb-1: full database mirroring (all tables are replicated everywhere) with an optional policy specifying how distributed queries (writes/commit/rollback) completion is handled (when the first, a majority or all backends complete).
  • RAIDb-1ec: full database mirroring (like RAIDb-1) with error checking for byzantine failures detection.
  • RAIDb-2: partial replication (each table must be at least replicated once) with optional policies for new table creation (like RAIDb-0) and distributed queries completion (like RAIDb-1).
  • RAIDb-2ec: partial replication (like RAIDb-2) with error checking for byzantine failures detection.

This technology is great for the open source databases because it allows you to cluster them easily. MySQL does support replication, and there are some solutions for PostgreSQL as well but I think something like this is more flexbile at the moment. The one drawback is that all applications that access the db must use JDBC.

Working with PostgreSQL

I'm working on migrating a SQL Server database to PostgreSQL. So far it has gone smooth, I did run into two issues today however.

I wrote some scripts that generate the DDL for PostgreSQL from my SQL Server metadata, the scripts also grab all the data, and create INSERT statements (I should probably be using COPY statements). So I have a 5MB file that contains the insert statements, and there was an error somewhere in there. I managed to figure out (after a lot of grep's) which line the error was on, it wasn't obvious to psql because it was a termination issue with a single quote. Here's what the query looked like:

INSERT INTO someTable (someColumn)
VALUES ('This is the content \')
Single quotes are escaped in PostgreSQL with either another single quote ('') or with a backslash. Turns out one of the columns in one of the tables ended with a \ so PostgreSQL just escaped the ending '

The next problem I ran into was with the bit datatype. I use a bit in SQL Server to represent booleans, so I assumed that in PostgreSQL a bit would have the same semantics. The bit datatype in PostgreSQL can actually hold a string of bits, not just 0,1, or NULL like in SQL Server. So a query like this:

SELECT * FROM news WHERE archived = 0
Won't work on PostgreSQL server if archived is of the bit datatype. You would have to do something like this:
SELECT * FROM news WHERE archived = B'0'
Which cast's the string '0' to a binary bit value.

I'd rather not change any SQL code in my applications, so I will be mapping my bit types to PostgreSQL's boolean type. It's actually a handy type that allows for more than just 0/1. You can use the following values for true:

And the following values for false:
This is nice because it corresponds to ColdFusion's boolean datatype.

Another way to resolve this problem would be to use a numeric type, such as integer. Many developers prefer to use integer datatypes over a bit or boolean, because performance is better. Using an integer does require more storage space however.

UPDATE the boolean type requires single quotes around 1 or 0, so in order to keep SQL code consistant I will be using the integer datatype.

Monday, April 28, 2003

ColdFusion Conference on a Boat

Actually it's on a large boat, a cruise ship and will be sailing in the Caribbean! You have until thursday (5/1/03) to signup, there is still some room left for you.

I'm ofcourse talking about the 1st. Annual ColdFusion Cruise-N-Learn, it's a week long cruise where you can learn about ColdFusion, and hang out with folks like Ben Forta and myself. It will be a small event so you will have VIP access to the speakers.

The Cost starts at $1995 all inclusive, plus you get $200 of on ship credit. The $1995 cost can be split between two people if you want to bring your spose, friend, or coworker to share a cabin with. I think that's a pretty good deal, so I hope to see you there.

Thursday, April 24, 2003

Macromedia Central, and Synchronized Applications

Macromedia has a presentation about the upcoming Macromedia Central platform.

The presentation notes that there are 750,000 Flash developers, and there is a $2.2B market for these "Permium Internet Content Applications" (Jupiter Research). I hope all the flash developers don't work on these because that only leaves each developer with just under $3000 :).

I'm interested to get a look at the API that central will provide developers. One thing I'm perticurally interested in these days is applications that synchronize data. I use at least 3 different computers on a regular basis (work, laptop, home pc), should I have to maintain 3 different address books? Definetly not. I think Macromedia Central will be a good platform for developing such applications, though from what I understand creating this synchronization would still be on the sholders of the app developers. (By the way I do have an app for keep my address book sync'd, I use IntelliSync for Yahoo, it sync's your Outlook and Yahoo! address books. It doesn't work perfectly however)

Wednesday, April 23, 2003

Microsoft Research

You can find lots of research infromation from the Microsoft Resarch web site. Microsoft funds quite a bit of research, and works with universities a lot. You will want to check out the projects page that lists all the projects they are or have worked on. Some of the research areas include Databases, Software Engineering, Security, Performance and Load Testing, Social Computing, Networking, etc.

Lots of interesting research there, just reading the description of some of the topics is enough to get you thinking let alone the research papers...

You will also want to check out the Multi University Research Lab. You can watch seminars on this site.

I first found this site a few years ago, and just thought of it again today, they have added several projects since then.

Tuesday, April 22, 2003

New ColdFusion MX book published

A new ColdFusion MX book called The ColdFusion MX Developers Cookbook was recently published by SAMS. I Co-Authored the book with Brad Leupen, and Chris Reeves.

The main difference between this book and other ColdFusion books is the format. It is setup as follows:

Technique - Explain the problem in one or two sentences
Example - Show the code to solve the problem
Comments - Discuss the problem, and the solution in detail

I think the main benefit to that format, is that it works well for both beginners and advanced people. Advanced developers can get the solution in as few words as possible. Beginners can see the solution, and then learn more about it.

The book doesn't cover the fundamentals of ColdFusion, or Programming, it assumes you know how to use what a variable is, and what a conditional is. We had the benefit of assuming the reader was comfortable with these fundamental skills when we wrote it. So if your not comfortable with the fundamentals you should check out some of the other books on the market, and then buy this one :).

Friday, April 18, 2003

Returning TOP N Records

Returning only the first N records in a SQL query differs quite a bit between database platforms. Here's some samples:

Microsoft SQL Server

SELECT TOP 10 column FROM table

PostgreSQL and MySQL

SELECT column FROM table


SELECT column FROM table

Due to these differences if you want to keep your code database independent you should use the maxrows attribute in the cfquery tag. The tradeoffs to database independance is performance, I would expect maxrows to be slower than specifying the rows in the SQL.

<cfquery datasource="#ds#" maxrows="10">
  SELECT column FROM table

PostgreSQL has a cool feature that will let you return an arbitrary range of rows (eg return rows 10-20). This is very handy for displaying pages of records:

SELECT column FROM table

The above query will return rows 20-30

Wednesday, April 16, 2003

SourceForge has RSS feeds

SourceForge, the huge repository for open source projects now has RSS feeds for each project including Project News, File Releases, Documentation, and project summary. This must be a new feature, I haven't noticed it in the past, but I could be wrong. Anyways that is a good way to keep upto date with your favorite open source projects. They also have a feed for all new releases.

Tuesday, April 15, 2003

Free ColdFusion Magazine

There is a free monthly ColdFusion magazine in the works. You can signup to receive it throught the web site. The magazine is being put together by Pablo Varando of EasyCFM.com.

Monday, April 14, 2003

Confirming Transaction support

Want to know if your ColdFusion database driver supports transactions (the <cftransaction> tag)? I was wondering how I might test this, and I came up with a solution. The code I wrote essentially creates a dead lock if transactions are supported by the db driver, if the timeout is reached an exception is thrown, and we know that our database and driver support transactions.

The Code: (warning I wouldn't run this against a live database, because it does cause a deadlock)

  <cfquery datasource="#ds#">
  	UPDATE table 
	SET column = 'value'
	WHERE id = 1
    <cfhttp url="http://localhost/deadlock.cfm" 
	  method="get" timeout="5" throwonerror="true">
    <cfcatch type="any">
 	  Transactions work!
  <cfquery datasource="#ds#" name="data">
  	SELECT column FROM table
	WHERE id = 1

<cfdump var="#data#">

Now create a file called deadlock.cfm if possible put this file on a different server, the <cfhttp> call above should call this file.

<cfquery datasource="#ds#" timeout="8">
  	UPDATE table 
	SET column = 'deadlock'
	WHERE id = 1

If the page says "Transactions work!", then transactions ofcourse seam to be working. I used this method to check transaction support of PostgreSQL 7.2.3 running on Redhat 8, using ColdFusion 5 on Windows with the PostgreSQL 07.02.0005 ODBC driver. And they do indeed work.

I may also check the mySQL odbc drivers, connecting to a mySQL 4.x database, mySQL 4.x supports transactions using the Berkley DB, or InnoDB file formats (not the default MyISAM table format), but I still need to install 4.x it on my server. If anyone has this setup, or has already tested please let me know.

Friday, April 04, 2003

Fast XSLT - Compiled XSL with XSLTC

An article on xml.com - Fast XSLT talks about the race for building faster XSL transformers. One approch focused on is generating a "translet" (a java class) from the style sheet, then executing the compiled class. Compiled execution is great, but compiling isnt. I would hope that application servers that plan to use XSLTC would do it in a transparent way (such as how JSP is compiled into a servlet and then cached behind the scenes).

It would be cool if you could write Java code under your web root, and then have the java code compiled automatically by the ColdFusion server. That is one feature I had wished CFMX would have. However I think this could be implemented on your own with a filter, and a fancy class loader.

Thursday, April 03, 2003

Using CustomTags in ColdFusion

Using custom tags in the presentation layer can greatly organize your code. Here's a quick start guide that I wrote up. Building a simple ColdFusion custom tag is as easy as:

A simple custom tag

create a file called todaysdate.cfm:

<cfoutput>#DateFormat(Now(), "mm/dd/yyyy")#</cfoutput>

Then place todaysdate.cfm in ColdFusion server's CustomTags directory, or in the same directory that you will call it from. To call it simply create a page with the following:


Using attributes

To pass an attribute into a tag, is also fairly easy.
<cfparam name="attributes.name" default="Dude" type="string">
<cfoutput>Hello #attributes.name#!</cfoutput>

Now to call it:

<cf_greet name="Pete">

In the greet tag there is an attribute called "name" which we passed the value "Pete" to in our example. We can access attributes using the attributes scope, attributes.attributename. In this tag we used the <cfparam> tag to set the default value of the name attribute to "Dude".

Using start and end tags

Another thing you can do with custom tags is to use start and end tags. Something like this:

<cf_myTag> This is some content </cf_myTag>

To access the content inside the tag we use another scope called thisTag. The thisTag scope contains variables that hold information about the tag that is being executed, such as the content between the start and end tags. Such content may be accessed with the variable thisTag.generatedContent.

Because you may want to do some processing when the start tag is invoked, and then some more when the end tag is invoked, your custom tag will file will be executed twice when you use an end tag. Luckily you can use the variable thisTag.executionMode to determine if your currently executing the start tag or the end tag. Lets consider a highly trivial example, of creating a ColdFusion tag to make text bold, there are several ways we can do this. Here is the simplest:

<cfif thisTag.executionMode IS "start"><b><cfelse></b></cfif>

The above tag will output a <b> tag when the start tag executes, and a </b> tag when the end tag executes.

Another way of solving this problem is to use the thisTag.generatedContent variable:

<cfif thisTag.executionMode IS "end">
	<cfset thisTag.generatedContent = 
		"<b>" & thisTag.generatedContent & "</b>">

In this case we are resetting the value of thisTag.generatedContent to include the <b> tags. When the end tag is finished executing ColdFusion will output the contents of thisTag.generatedContent.

Note that the value of thisTag.generatedContent is not set until the end tag begins executing. Setting the value of it in the start tag execution mode will have no effect on the output.

A third way to solve this problem is similar to the last, but in many cases this will be the way to go:

<cfif thisTag.executionMode IS "end">
	<cfset thisTag.generatedContent = "">

In this example your handling the output yourself, and setting the value of thisTag.generatedContent to an empty string. This is the way to go if your using a lot of conditionals to produce your output.

A few more tricks we can use to ensure that our tag is being called properly include:

To ensure that the end tag is present:

<cfif thisTag.executionMode IS "end">
	Do something.
<cfelseif NOT thisTag.hasEndTag>
	<cfthrow message="Missing end tag.">

To ensure that the file is only called as a custom tag:

<cfif NOT IsDefined("thisTag.executionMode")>
	Must be called as customtag.<cfabort>
<cfif thisTag.executionMode IS "end">
	Do something.

<cfelseif NOT thisTag.hasEndTag>
	<cfthrow message="Missing end tag.">

Update 4/4/03:Ray Camden also suggested this handy code snippet:

To ignore an end tag:

<cfif thisTag.executionMode is "end">

That code simply ignores the end tag. This is useful if your trying to use valid XML within your CFML, such as <cf_mytag />. Many people have gotten in the habit of doing that now, but keep in mind that CFML is not valid XML, mainly CFIF statements tend to break the rules.

More bashing

Thanks to my brother Steve, I was able to get my backtracking cd to the way I wanted it to

Just add the following to your ~/.bashrc or if you want to make this work system wide add this to /etc/bashrc:

#redefine pushd and popd so they don't output the directory stack
    builtin pushd "$@" > /dev/null
    builtin popd "$@" > /dev/null

#alias cd so it uses the directory stack
alias cd='pushd'
#aliad cdb as a command that goes one directory back in the stack
alias cdb'popd'

The redefinition of pushd and popd redirects their output to /dev/null instaed of your terminal. This prevents them from displaying the entire stack every time they are called

Tuesday, April 01, 2003

Backtracking with bash

I was working with linux quite a bit today, and frequently changing between directories, when I wondered if there was a way to go back to the directory I was in previously.

Turns out there is a way:

 cd ~-
So if I was doing something like this:
[pete@bigred /]$ cd /etc
[pete@bigred etc]$ cd /usr/local
[pete@bigred local]$ cd ~-
[pete@bigred etc]$ pwd
If you want to create a command so you don't have to type ~- you can create an alias:
alias cdb='cd ~-'
This ~- thing works great if you only need to go back one directory, but what if you wanted to go back two directories. Continuing the last code sample:
[pete@bigred etc]$ cd ~-
[pete@bigred local]$ cd ~-
[pete@bigred etc]$ pwd
We are back to /etc and not / our starting point. What I want is something that keeps a history of the directories I've been to.

It turns out that the Bash (the "Bourne again shell") has a directory stack builtin. Three command line tools for manipulating the stack are avaliable dirs, pushd, and popd. More info about the directory stack in bash here.

If we pushd a directory onto the directory stack, we can retreive the top of the stack using dirs +1. I tried setting up some aliases to get it to work the way I wanted:

alias cdd='pushd'
alias cdb='cd `dirs +1`'
Those worked a bit, but I ran into a lot of problems, especially when in the home directory. Also when you run pushd, popd, or dirs it always prints the contents of the stack, I don't know how to suppress that. So I figured I would post it here, and see if anyone can come up with a solution, or if anyone knows of a better way of going about this.

Isn't it funny how software developers will spend hours of time trying to save a few seconds of their future time.

Tuesday, March 25, 2003

Apache Module source code included in Updator 3

Damon Cooper (of Macromedia) pointed out today on CF-Linux:

"By the way, you guys knew that source code and build instructions for the Apache web connectors was now included, correct?"

That's cool, I beleive its only on the Unix versions though, I couldn't find it in my windows install. I'll check my linux install when I get around to it. This will hopefully resolve some of the issues people have been having with Apache Magic number's etc.

Tuesday, March 18, 2003

Backing up ColdFusion Datasources

If you want to backup datasources on ColdFusion 5 and below on windows, backup the following registry keys:


Create two reg files, and then just double click the reg file on the server you want to backup on. If your only using OLE DB datasources, then I beleive you only need to backup the first key. Also it may be a good idea to keep a backup of your the entire ColdFusion registry key.

On ColdFusion MX settings are stored in files (typically xml using WDDX) instead of the registry. So you need to backup the files that contain the settings. The file cfusionmx\lib\neo-query.xml stores the datasources.

Editing Text Files

Developers and system administrators often need to open files of types that aren't mapped to a particular program. This ofcourse requires that slow "Open With" window to pop up. A trick I recently found is to add a shortcut to the right click menu, to open files with notepad.

This is done by editing the registry, under HKEY_CLASSES_ROOT\*\ There may or may not be a key under the * called Shell, if its not there create a key called Shell under HKEY_CLASSES_ROOT\*\. Under the Shell key create a key called Notepad, and under notepad create a key called Command. So now you shold be in HKEY_CLASSES_ROOT\*\Shell\Notepad\Command. Set the value of (Default) in the Command key to be notepad %1 or the path to another text editor.

Now when you right click on any file there will be a item in the menu called Notepad, that you can use to open the file with notepad.

Saturday, March 15, 2003

Server side Flash Detection

It would be useful if it worked reliably. According to the Flash 6 release notes "The player installation process now configures the browser to add the Flash MIME-type (application/x-shockwave-flash) to the HTTP Accept header. This enables server-side Flash Player detection." This worked fine on Internet Explorer on Windows, but with Netscape 7.02 using the flash player that comes with it, it doesn't add the header.

Here's some ColdFusion code to test this out:

<cfdump var="#GetHTTPRequestData()#">

<cfset req = GetHttpRequestData()>
<cfif req.headers.accept contains "application/x-shockwave-flash">
You have Flash 6 or above.

Additionally the HTTP accept header sent by IE when you reload the page is just "*/*", causing potential problems even if the header was present on all browsers.

Server side flash validation would be very useful, especially for remoting apps where Flash 6 is requeired anyways. It would have been a clean way to perhaps display a HTML version of the application.

I will test this out some more next week (I'm curious how it will work on Linux) when we get back to the states.

Thursday, March 13, 2003

Heading North
I'm heading to Toronto today for MXNorth. There will also be two other people from CFDEV there (Greg, and Rob). We are sponsering Friday's lunch, and we also have a booth, so stop by and chat with us.

Thursday, March 06, 2003

Macromedia got a new site

I realize I'm a day late on the news here, but I'm quite impressed with the amount of feedback Macromedia's new web site has generated. Just about every mailing list I'm on has a large tangent oriented thread that started with a mention of the new site. I wish I could generate that much feedback when I redesign a web site (did you notice I changed the top graphic of cfdev.com about a week ago, no one noticed, it was a subtle change).

Anyways I think it is a positive step for Macromedia, and the technologies they push. It's great as a developer to see Macromedia finally using their own technologies. I'm sure they learned a lot about their products while developing applications using them, I know I have found that to be the case with reguards to products I have built.

Friday, February 28, 2003

Turning a JDBC Result set into a ColdFusion query

Recent discussion on the CFCDev mailing list (at cfczone.org) shows how to return a ColdFusion query object from a Java class using a JDBC result set (java.sql.ResultSet). The solution posed by both Brandon Purcell, and I was to pass your JDBC result set in to the constructor of the coldfusion.sql.QueryTable class. Joe Eugene tested the hypothisis, and asserts that it does work, but is slower then returning the result set, and navigating through using the methods of the ResultSet class.

The coldfusion.sql.QueryTable class comes with ColdFusion MX (this technique will only work on CFMX), and is located in the cfusion.jar file. You will need to add the cfusion.jar file to your class path before you can compile any java code that uses the QueryTable class (you don't need to worry about the classpath if you are accessing QueryTable via CFOBJECT, or CreateObject within CFML). More information can be found about the coldfusion.sql.QueryTable class here.

Some ColdFusion code to convert a result set to a Query object:

<cfset newQuery = CreateObject("java", "coldfusion.sql.QueryTable")>
<cfset newQuery.init( someObject.getResultSet() ) >

Some Java code to return a query from a java class (requres cfusion.jar in classpath)

import coldfusion.sql.QueryTable;
public class QueryUtil
  public static coldfusion.sql.QueryTable getColdFusionQuery(java.sql.ResultSet rs)
    return new coldfusion.sql.QueryTable(rs);

Thursday, February 13, 2003

More Info about ColdFusion MX on Redhat 8
Dustin Krysak contacted me in response to a recent blog entry ColdFusion MX works on Redhat 8. He me provided a detailed checklist for installing ColdFusion MX on Redhat 8, and allowed me to post it to cfdev: Steps Taken to Install CFMX on RedHat 8.

I should point out that Verity doesn't work on Redhat 8, and Redhat 8 still isn't officially supported by Macromedia. Steven Erat posted this message today on the CF-Talk mailing list "Just a word of caution, although most features of CFMX run on Red Hat 8.0, its not a supported version. The main problem is that binary files used in Verity won't work. There may be some other binary files used for other features and they won't work either."

Too bad verity isn't written in Java, maybe Macromedia can persuade Verity to do so (hint hint).

Tuesday, February 04, 2003

Disk Considerations on CFMX

When you install ColdFusion MX (in C:\cfusionmx\) with an alternate web root directory (lets say d:\web) the WEB-INF directory stays in c:\cfusionmx\wwwroot\WEB-INF\.

That isn't a huge deal but it has implications when you are using a different hard drive for your web files...

Lets say your C:\ drive is slower than the D:\ where you keep all your web files. All the generated servlets (class files), and CFC's class files will stay in the WEB-INF directory on the slower drive (C:\). Your also going to be taking up a lot of space on the C drive.

Many of the .class files will be cached, and you can set the cache size to be large enough to store all of them (in most cases). But when the server is restarted, the cache is lost. If you have tons of files access may be slower.

So unless you can figure out how to move the WEB-INF directory, your going to want to make sure that you install ColdFusion MX on a hard drive with enough space, and enough speed to handle your needs.

Friday, January 31, 2003

FTP Scripts on windows
I found this Microsoft KB article today 96269 which shows you how to use the ftp program that comes with all versions of windows an automate a file transfer.
ftp -s:script.txt ftp.server.com
The contents of script.txt might look like this:
cd /files
put file.zip
This is handy for administration between servers, but keep in mind that FTP sends passwords in clear text.

Monday, January 13, 2003

CFMX works on Redhat 8
I am subscribed to the CF-Linux list hosted at houseoffusion.com and I see a lot of people having problems installing CFMX on linux. Especially on Redhat 7.3. Macromedia has said that there were problems related to Java in RedHat 7.3 and urged customers to use RedHat 7.2.

Today I installed CFMX on RedHat 8.0 after running redhat's up2date utility (similar to windows update), and everything went fine. I wasn't sure if it would work because of what I have heard, so I figured I would post some positive results in case anyone is wondering. Keep in mind that I haven't tested all the features of CFMX like verity, etc.

ColdFusion 5 on Windows .NET Enterprise Server RC1
I tried installing CF5 a the release candidate of Microsoft's next server platform .NET Server, the results - negative. Ofcourse my first hint should have been when I first ran setup.exe it told me I was attempting to install ColdFusion on an unrecognized version of windows. I clicked continue anyways, and the install seamed to go smooth. I had to pick "Other Web Server" because IIS 6 wasn't detected (I planned to use apache). After rebooting I received numerous popup windows with the message:
Event Type:	Information
Event Source:	Application Popup
Event Category:	None
Event ID:	26
Date:		1/13/2003
Time:		1:02:12 PM
User:		N/A
Application popup: wsm.exe - Unable To Locate Component : 
This application has failed to start because WINSTRM.dll was not found. 
Re-installing the application may fix this problem. 

For more information, see Help and Support Center at 
After stopping ColdFusion services the popups stopped. I will work on this some more, but if you have gotten ColdFusion 5 to work on .NET server let me know. I also plan to try installing CFMX on it. I'll post the results when I do.