CFML wishlist: All collections should extend Iterator

Have you ever really given a second thought to the fact that in ColdFusion/CFML you have to loop queries, arrays, and structures in completely different ways?   For example, in each of these things, we are essentially doing the same thing:

<!--- looping our query --->
<cfloop query="myQuery">
	<cfset doStuff() />
</cfloop>
<!--- looping our array --->
<cfloop array="#myArray#" index="i">
	<cfset doStuff() />
</cfloop>
<!--- or --->
<cfloop from="1" to="#ArrayLen(myArray)#" index="i">
	<cfset doStuff() />
</cfloop>

<!--- looping our structure --->
<cfloop collection="#myStruct#" item="i">
	<cfset doStuff() />
</cfloop>

In each of these cases, we are essentially doing the same thing, that being looping a collection that contains multiple items and acting on each iteration.  I have always liked the fact that the ColdFusion array can be converted to a Java iterator like this:

<cfset iterator = myArray.iterator() />
<cfloop condition="#iterator.hasNext()#">
	<cfset thisIteration = iterator.next() />
	<cfset doStuff() />
</cfloop>

However, given the fact that <cfloop array=”#myArray#” index=”i”> is already an abstraction, it doesn’t make sense to use this in most cases.   But wouldn’t it be cool if you could call myQuery.iterator() or myStruct.iterator() and have the same functionality?  Or even better, why not have those collections all extend an iterator class so that it could be simplified even futher with myQuery.hasNext() or myStruct.hasNext().

Keep in mind, this discussion is only coming from the perspective of the programming interface itself, and I am not going to get into the differences behind the scenes of how a query result is actually a set of arrays of columns, or how an array differs from a struct.  My point is simply that if we have these abstractions, it sure would be cool if they were consistent, but we were still able to call specific functions on them like ArrayFind() , StructDelete(), etc.  If we had this ability, our loops in CFSCRIPT would be a lot more consistent as well.

With that said…. I will leave you with my wishful implementation for writing loops in CFML:

<cfloop condition="#myQuery.hasNext()#">
	<cfset thisRow = myQuery.next() />
	<cfset doStuff() />
</cfloop>

<cfloop condition="#myArray.hasNext()#">
	<cfset thisItem = myArray.next() />
	<cfset doStuff() />
</cfloop>

<cfloop condition="#myStruct.hasNext()#">
	<cfset thisItem = myStruct.next() />
	<cfset doStuff() />
</cfloop>

Refactoring: avoiding nested conditional statements

Recently at I was given the task of adding an new validation routine to an existing validation process.  In this piece of code, the requirements mandated that a series of sequential tests would be run, but in the event of a failure of any of them, the process would kick out and set an error state, provide user feedback, and whatever other tasks needed to occur.  We have all seen processes like this before.  Essentially it looked like this:

error = true;
if ( testOne() )  {
    if ( testTwo() ) {
        if ( testThree() ) {
            if (testFour() )  {
                 error = false;
                 doAllTestsPassedStuff()
            } 
        }
    }
}
if ( error ) {
	handleErrorCondition()
}

Looking at this block of code, the intent is pretty obvious as we progressively run tests as long as the previous test returned true, eventually firing the doAllTestsPassedStuff() method.  If any of the tests failed, we would call handleErrorCondition().  While this approach is completely functional, the maintainability of it is no fun, and it just feels wrong to me.  For the task I was given, I had to add a new test davesSuperTest()  between the 2nd and 3rd conditional blocks.   If I were to follow the previous approach, I would insert it there, and tab out the previous testThree() and testFour() conditional statements further to the right.  In my opinion this is an ugly block that is getting uglier by the minute.

By altering the approach to use try/catch blocks, we can still maintain the same level of control and order or operations as dictated in the requirements, but each condition becomes insulated from the others,  like this:

try {
	if ( !testOne() )	{
		throw "fail:testOne";
	}
	if ( !testTwo() )	{
		throw "fail:testTwo";
	}
	if ( !davesSuperTest() )	{
		throw "fail:davesSuperTest";
	}
	if ( !testThree() )	{
		throw "fail:testThree";
	}
	if ( !testFour() )	{
		throw "fail:testFour";
	}
	// if we reach this point, then all of the above tests passed.
	 doAllTestsPassedStuff()
}	
catch(e)	{
	handleErrorCondition()
}

Given this approach, it is very simple to add/remove conditions without disrupting other conditions, even better, I don’t have to scroll to my second monitor on the right!

How to set JAVA_HOME environment variable in Ubuntu

I am actually creating this blog entry as a bookmark for myself, but since I know that I never remember how to do it, others might benefit as well!

One way that you can set your JAVA_HOME variable and add to your PATH, is be doing the folowing.  As ‘sudo’ open up /etc/bash.bashrc and add the following to the end of the file.  NOTE: Set the java path to whatever the actual path is on your environment if it does not match /usr/lib/jvm/java

JAVA_HOME=/usr/lib/jvm/java
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin
export PATH

When you reboot, try running the following:

$ echo $JAVA_HOME
/usr/lib/jvm/java
 echo $PATH
[probably lots of paths]:/usr/lib/jvm/java/bin

`c->xlib.lock’ failed error on Java applications

I am currently using the Alpha 3 release of Ubuntu 8.04 Hardy Heron.  Considering the fact that it is an alpha release, I tend to not get worked up over little errors that might occur.  However, I have found one that I just couldn’t get around.  I use Aqua Data Studio for my database client and since loading Hardy Heron, I have been unable to run it.

When I would start it from a terminal, I would get a dump that looked like this:

#0 /usr/lib/libxcb-xlib.so.0 [0x90d00767]
#1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_unlock+0x31) [0x90d008b1]
#2 /usr/lib/libX11.so.6(_XReply+0xfd) [0x9039429d]
#3 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so [0x9063e8ce]
#4 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so [0x9061b067]
#5 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so [0x9061b318]
#6 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so(Java_sun_awt_X11GraphicsEnvironment_initDisplay+0x2f) [0x9061b61f]
#7 [0xb4cff3aa]
#8 [0xb4cf7f0d]
#9 [0xb4cf7f0d]
#10 [0xb4cf5249]
#11 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/server/libjvm.so [0x637338d]
#12 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/server/libjvm.so [0x64fd168]
#13 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/server/libjvm.so [0x6373220]
#14 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/server/libjvm.so(JVM_DoPrivileged+0x363) [0x63c90d3]
#15 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/libjava.so(Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2+0x3d) [0xb7d1096d]
#16 [0xb4cff3aa]
#17 [0xb4cf7da7]
#18 [0xb4cf5249]
#19 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/server/libjvm.so [0x637338d]
java: xcb_xlib.c:82: xcb_xlib_unlock: Assertion `c->xlib.lock' failed.
Aborted (core dumped)

Considering the fact that I used the Ubuntu sun-java6-jdk package from the Ubuntu repository, I decided that I would try the self-extracting bin that is available on http://java.sun.com.  After swapping to that JVM, I still received the same dump and abort.  After doing a bit of searching, I came across a patch in one of the bug reporting forums that effectively patches your JVM and prevents this error from occurring.  I ran the patch and now everything works as it should.   If you are receiving this error, create a shell script with the following content and run it.  Assuming that it runs successfully, you should then be able to open the Java application that was failing.

#!/bin/sh
# S. Correia
# 2007 11 21
# A simple script to patch the java library in order
# to solve the problem with "Assertion 'c->xlib.lock' failed."
# see bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6532373
LIB_TO_PATCH=libmawt.so
for f in `find /usr/lib/jvm -name "$LIB_TO_PATCH"`
do
echo "Patching library $f"
sudo sed -i 's/XINERAMA/FAKEEXTN/g' "$f"
done

Big thanks to “S. Correia” for getting me back on my feet!

SeeStack online stack trace tool

I spent far too much of my day yesterday pouring through stack traces and metrics dumps and trying to find something that has been killing the performance on one of our applications. In the process, I came across a really (and I mean REALLY) cool online stack trace parser called SeeStack, offered by Webapper, the guys behind SeeFusion. You can either upload or paste in your stack trace and it gives you back a nicely parsed and formatted report that makes it very easy to spot threads that have not budged since the previous stack. Using this tool we were quickly able to spot some trouble spots with the application (or as it turned out, the database….).

For a quick sample of how this works, try uploading this file.

Using Java instead of CFFILE and CFDIRECTORY

There are several reasons why jusing Java in place of CFFILE of CFDIRECTORY might be a good idea.  In many cases such as shared hosting environments, hosts block use of those tags.  While it obviously goes against the spirit of their intent of doing this, sometimes applications just need that functionality and this becomes a real roadblock for developers.

Secondly and in my opinion a very important reason is for performance.  Jusing Java to perform these tasks can be 10-20 times faster than using tag calls.  Fellow CF’er Phillip Holmes offers this reason: The reason why the Java example is much faster is because when you call the cffile tag, you’re actually calling a class that groups Java functionality together. This class is located in the lib/cfusion.jar file. By using the call to the Java.io namespace, you’re bypassing the excess functionality and error checking that CFMX does for you. So, you’re streamlining your operation by not instantiating code that you don’t use.

Reading a directory:
First let’s read a directory.  One thing that is worthy of mention is that this method will return an array rather than a ColdFusion query object, so this might not be just a plug-n-play change to code that has existing cfdirectory calls.  You will likely have to change the way you are accessing the returned data.  So, how do you do it?

<cfscript>
ourDirectory = expandPath(“./”);
directoryList = createObject(“java”,”java.io.File”).init(ourDirectory).list();
</cfscript>

This is obviously a bit more code to have to type out, so you may want to keep a UDF available that returns your array when a directory is passed to it.

Writing a file:
Trevor Burnette has given a great example of how to write files with using Java instead of CFFILE. I have tried this and found tremendous performance gains using his method. Go check out his blog for some good info.