Google AJAX Library CDN Versioning

It’s amazing what you find when you read the documentation. Since I always forget the address for Google’s CDN hosting of jQuery I have to search for it each time. This time when I found the address I was looking around a bit and found out this interesting tidbit that I didn’t know before about Google’s CDN for their AJAX libraries.

Specifying a version of “1.8.2″ will select the obvious version. This is because a fully specified version was used. Specifying a version of “1.8″ would select version 1.8.4 since this is the highest versioned release in the 1.8 branch. For much the same reason, a request for “1″ will end up loading version 1.9.1.

Google AJAX Libraries API Developer’s Guide

For example, if I were linking to jQuery I would normally have used the following and updated semi-regularly:

http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js

But if I just want the latest for the “1.3″ version I could reference:

http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js

Or if I was feeling really risky and trust jQuery not to break between versions:

http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js

Hope its as useful to others as I found it!

Railo Express with Multiple Local Hosts

This is how you can configure Railo Express to use Jetty virtual hosts and local host file entries to point to a single Railo Express installation. This was extremely useful while developing applications that power multiple domains.

For this example, we are going to add a virtual host for the snow.ftd host.

Jetty Setup

Jetty makes it really easy to configure virtual hosts for a context.

The configuration file in Railo Express at {railo-express-directory}/contexts/railo.xml already has the configuration setup to start us off:

<!-- virtual hosts
<Set name="virtualHosts">
	<Array type="String">
		<Item>www.myVirtualDomain.com</Item>
		<Item>localhost</Item>
		<Item>127.0.0.1</Item>
	</Array>
</Set>
-->

Uncomment the block of code and change the item to match the snow.ftd host name like so:

<!-- virtual hosts -->
<Set name="virtualHosts">
	<Array type="String">
		<Item>snow.ftd</Item>
	</Array>
</Set>

Local Host Setup

I already posted instructions for adding local hosts to your Snow Leopard. You can follow the directions there to setup your desired host. In linux you can modify your hosts file in a similar fashion. There may even be a way to change your hosts file on windows, although I have never done so.

Testing

Once the Jetty config and the local hosts have been updated, restart Railo—if it is running—and go to snow.ftd:8888 in your browser. You should see the same page available at localhost:8888.

And you are done! You can now add as many hosts as you need!

Local Host Entries on OS X Snow Leopard

Today I wanted to setup local host entries on my MacBook. Searching around I found several articles about editing the /private/etc/hosts file to add local domains entries pointing back to my computer. I don’t know if it is something that changed with Leopard or Snow Leopard but it just wasn’t working for me. Even restarting the computer was a no go.

Using the dscl Utility

With the wonder of Google searching and the generous comments of others I found out about the dscl utility.

Listing Host Entries

To see what is listed for your hosts at any time just run this command:

dscl localhost -readall /Local/Default/Hosts

Adding a New Entry

In this example I am going to have the snow.ftd host point to my 127.0.0.1 IP address:

sudo dscl localhost -create /Local/Default/Hosts/snow.ftd IPAddress 127.0.0.1

You should now be able to ping snow.ftd and have it resolve to your local computer.

Removing an Existing Entry

If you decide you do not want an entry anymore just run this command to remove it:

sudo dscl localhost -delete /Local/Default/Hosts/snow.ftd

Reading the BSD Flat File

It was also noted that you can read the BSD flat file using this command:

dscl localhost -readall /BSD/local/Hosts

ColdFusion 9 Ternary Operator Fail

One of the things that I was really excited for in ColdFusion 9 was the support for the ternary operator. As Ben said:

To me, the ternary operator is what the IIF() method call always wanted to be.

Unfortuately I was testing some CFML code, written and working on Railo, on a ColdFusion 9 server and had this error pop up:

Unable to find an operator implementation for coldfusion.compiler.ASToperator

Turns out the the ternary operator works great… unless you are using it in a default value for an argument. Fail.

Here is an example, that should run fine if the ternary operator was doing what it is supposed to:

<cffunction name="testing" access="public" returntype="void" output="false">
	<cfargument name="test" type="string" default="#(1 EQ 1 ? 'Hi' : 'Bye')#" />

	<!--- Anything --->
</cffunction>

I have filed it as a bug if you would like to vote on the issue.

ColdFusion Development using VirtualBox and Ubuntu 9.10

Here is how I setup a VirtualBox Virtual Machine (VM) running Ubuntu 9.10 Server edition for ColdFusion development on my MacBook Pro.

Step 1: Download Needed Files

The first step is to download all the files you will need. Since the downloads usually take some time we’ll get them out of the way first.

For my installation I wanted to get more familiar with the Server edition of Ubuntu and to require fewer resources. You should be able to do a similar installation with the Desktop edition.

Step 2: Install VirtualBox

Once you have downloaded all the files, run the VirtualBox installer.

If you would like to learn more about VirtualBox the installation comes with a user manual or you can download a pdf copy from their download page.

Step 3: Create an Ubuntu Virtual Machine

Click the New icon in VirtualBox to start the wizard for adding a new VM.

  1. Click Next to start the wizard.
  2. Enter Ubuntu CF for the Name of the VM.
  3. Select Linux and Ubuntu in the OS Type drop downs.
  4. Click Next.
  5. Click Next to accept the default amount of RAM. (You can adjust if you want to…)
  6. Click Next to create a new hard disk image to use for the VM.
    1. Click Next to start the wizard .
    2. Click Next to create a dynamically expanding storage.
    3. Click Next to accept the default name and size.
    4. Click Finish to accept the choices for the disk image.
  7. Click Finish to end the wizard.

Step 4: Install Ubuntu

Now that there is a VM setup to hold the guest Ubuntu system we need to install Ubuntu on it.

In VirtualBox Double Click on the Ubuntu CF listed in the left column to start up the VM. Since this is the first time you are starting the VM it will bring a up a First Run Wizard to guide you in setting up the new VM.

  1. Click Next to start the wizard.
  2. Change the Media Source to Image File and click the Other... icon.
    1. Click the Add icon along the top.
    2. Select the ubuntu-9.10-server-i386.iso file we downloaded earlier.
    3. Click Select with the ubuntu-9.10-server-i386.iso item selected.
  3. Click Next to continue.
  4. Click Finish to end the wizard.

The VM should now startup and bring up the installation the Ubuntu. I’m not going to go into the details of installing Ubuntu here, so just continue with the next step once Ubuntu installation is complete. Also, since we are going to be using apache you may wish to have the setup create a LAMP server configuration when choosing features or you can install it manually afterwards.

Step 5: Setup Guest Additions

In order to have the Shared Folders work we will need to install the Guest Additions.

Before we install the Guest Additions we will need to install dkms:

sudo apt-get install dkms

To mount the Guest Additions disc image to the VM press Command + D or select Devices > Install Guest Additions... from the VM menu. Then install the Guest Additions by running:

cd /cdrom
sudo sh ./VBoxLinuxAdditions-x86.run

Step 6: Setup Shared Folders

One of the goals when creating the virtual machine was to be able to edit the files natively but run them on the guest operating system that reflects the production environment.

With shared folders we are able to use a local directory as a share on the guest VM.

Before we add the shared folder we need to have a folder to share. For this example I’m using the directory I created at /Users/randy/Documents/cf9/.

With the VM powered off edit the Settings and select the Shared Folder icon.

  1. Click the Add a new shared folder definition icon on the right side.
  2. Enter the Folder Path (/Users/randy/Documents/cf9/) or select Other... from the drop down and locate the directory.
  3. Enter the name you would like the share to be referenced as in the Folder Name field. In this case I am going to call it cf9.

Now that we have the shared folder available to the VM we want it to mount the share each time the VM starts. To do this we startup the Ubuntu VM and edit the /etc/fstab file and add the following line at the end of the file (note that you will need to change the username to match your user):

cf9	/home/randy/Documents/cf9	vboxsf	uid=randy,gid=users	0	0

You will also need to create a blank directory at /home/randy/Documents/cf9 that the share will mount to.

The next time your VM is started it should have access to /Users/randy/Documents/cf9 on the host machine at /home/randy/Documents/cf9 on the guest machine.

Step 7: Enable Port Forwarding

To setup the port forwarding you will need to stop the VM. In the terminal run the following commands to setup the port forwarding. (Note that "Ubuntu CF" needs to match the name of the VM created above.)

VBoxManage setextradata "Ubuntu CF" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guesthttp/Protocol" TCP
VBoxManage setextradata "Ubuntu CF" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guesthttp/GuestPort" 80
VBoxManage setextradata "Ubuntu CF" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guesthttp/HostPort" 8580

This will change the VM settings to have the guest port of 80 (which is the default apache port) of the guest forwarded to port 8580 on the host. Without this you would not be able to talk to the guest operating system.

Step 8: Install ColdFusion

Since we already downloaded the installer for ColdFusion we just need to get that file to the VM. Luckily we already setup a shared folder so if you move the installer to the /Users/randy/Documents/cf9/ directory it will be available in the VM.

To run the ColdFusion installer:

cd /home/randy/Documents/cf9/
chmod +x ColdFusion_9_WWE_linux.bin
sudo ./ColdFusion_9_WWE_linux.bin

This should start the installer. During the installation, apache should be configured to run with ColdFusion.

Step 9: Test Environment

To test that the development environment is working correctly you should be able to place an index.cfm file in your /Users/randy/Documents/cf9/ directory. Make sure that you place some CFML in the file to test that ColdFusion is doing it’s thing. Then visit http://localhost:8580/ in a browser on your host to test out the new development environment!

Upgrade Jetty in Railo Express

There was a bug in Jetty that was causing MXUnit ant tests to not work because it was double encoding the cookies. The bug was fixed in Jetty but Railo had not released a new Express version with the fix. I found out that it is quite simple to upgrade:

  • Download and unarchive the version of Jetty you are upgrading to (ex: 6.1.20).
  • Stop Railo Express.
  • Delete the old jetty and jetty-util jars from the Railo Express /lib directory (ex: jetty-6.1.2.jar and jetty-util-6.1.2.jar).
  • Copy the jetty-6.1.20.jar and the jetty-util-6.1.20.jar from the jetty lib/ directory to the Railo Express lib/ directory.
  • Start Railo Express.

Not much too it, but it seems to be working just fine and the MXUnit ant tasks are now running as expected.

Automate WordPress Upgrade on Grid Server

Many of the domains and sub-domains on my Media Temple Grid Service contain installations of WordPress. Since I don’t want to be bothered by a normal upgrades here is how I install WordPress in a way that allows for simple upgrades.

This is not a completely automated solution, there is more that you could do to improve the process, but it should save a lot of the time normally spent updating WordPress.

Note: the provided script will only work if you do the WordPress install using subversion and in the domain/sub-domain’s html/ directory.

Installing WordPress

Yes, there is a 1-click install for installing WordPress on the (gs), but I don’t use it. Here is how I install WordPress on a domain or sub-domain (ex: blog.site.org):

  1. Ensure that you have an alternate domain or sub-domain created that has an empty html/ directory.
  2. Find the latest tag listed in the WordPress repository. (ex: 2.8.3)
  3. SSH into the (gs) as the serveradmin.
  4. cd domains/blog.site.org/html
  5. svn checkout http://svn.automattic.com/wordpress/tags/2.8.3/ ./ --force

Once the svn checkout is complete you should be able to visit the install page (ex: blog.site.org/wp-admin/install.php) and finish the installation of WordPress like normal.

I also suggest you take steps to harden your WordPress install.

Upgrading Many WordPress Installs at Once

When you learn of a new version of WordPress you can do the following to easily upgrade all of your installations at once.

  1. SSH into the (gs) as the serveradmin.
  2. You will need to upload the updateWP bash script to your serveradmin home directory (~/) if it does not already exist.
  3. Run the bash script with the new version number: ./updateWP.sh 2.8.4
  4. The script will look at each of your domains to see if you have WordPress installed. If it finds WordPress it will switch to the new tag.
  5. After all the installs are updated you can view the updateWP.log to see all of the installations that were completed. On some tags you may need to go to each of the /wp-admin/ page and manually tell it to update the database. You can check if this is necessary by visiting one of your WordPress install’s /wp-admin/ directory.

AIR Update Checking Using Mate

While working on an AIR project hosted on Google Code I wanted to setup automatic updates. I wanted the entire project to be self contained and not require any supporting websites. After a little coding I can now use Mate and dispatch an event to check for updates.

Preparing for Updating

In the main mxml document I add a namespace for my ef-flex event maps (xmlns:efmaps="com.ef.air.maps.*") and the following line:

<!-- Automatic update event map -->
<efmaps:UpdateEventMap />

Once included, the Mate knows how to handle the update event and is listening for it. See the prosperonair main mxml for an example.

Automatic Update Checking

Using the event driven nature of Mate to check for an update–automatically or manually–is now as easy as dispatching an event. See the prosperonair event map for an example.

To automatically check for an update edit the application’s event map, add the import for the UpdateEvent, add an event handler for the AIREvent.WINDOW_COMPLETE event, and add the following (changed for your project):

<!-- Automatically check for newer version -->
<mate:EventAnnouncer generator="{UpdateEvent}" type="{UpdateEvent.CHECK}">
	<mate:Properties isAutomatic="true" versionURL="http://project.googlecode.com/svn/trunk/version.xml" />
</mate:EventAnnouncer>

Manual Update Checking

The process for checking for an update manually is almost identical to the automatic update check save for changing the isAutomatic property to false. This lets the updater know that the user should be notified when there is no update.

Version XML File

For the updater to work correctly you will need to have a XML file in your repository that the application will use to check if it has the latest version. You can read more about the format the xml file needs to use in the official documentation for the ApplicationUpdaterUI. Be sure that you pass the correct url of the XML file when doing an update check.

The Code

The code used in this post is available in the prosperonair and ef-flex projects. The main code of interest that performs the update can be seen in the UpdateManager.as file.

Aperture Vault on Amazon S3

As I amass more photos I get squeamish. Photos are some of the most valuable data on my computer besides the code I write. My code generally isn’t a big worry because it is being versioned and usually exists in several working copies so the risk of loss is smaller. With photos I have at best have a dvd backup of the originals along with a time machine backup. But if my apartment and computer goes up in smoke? It’s all gone.

With the wonderful advances in the cloud I decided to see what it could do for me. After doing a little searching I found a post or two about it and I decided to try it out myself.

To use Amazon’s S3 for the vault I need to have it be mounted as a drive. I chose to use a product called Jungle Disk to mount and manage my S3 account. Jungle Disk has clients for all the operating systems and a version for portable drives that has all three clients.

Once I had setup a bucket with Jungle Disk I was ready to create my vault with Aperture. The way that Aperture is programmed it won’t allow you to directly setup the vault on a network drive. To get around that I create the vault onto the desktop. Once the vault is created you will notice that it has the locked symbol next to it. I closed Aperture and removed the locked status from the file. Then I moved the vault onto the S3 drive.

I had about 35GB library of photos when I created the vault. Since this is all going over the internet it is going to take a while for all the files to copy over, which is to be expected. I was luckly on a university connection so the wait wasn’t as long as it was for some.

After the files all successfully copied over to the S3 account load up Aperture. Right click on the vault that was just created and select the Update Vault Path… From there you should be able to browse to your S3 network drive and select your vault.

When I had taken some more pictures and went to update the vault I found the big reason that I probably would not use the S3 for anything but periodic (quarterly or semi-annually) backups. When I updated the vault it seemed to want to touch and/or copy every file. If you are on a local drive this wouldn’t be much of a problem, but since you are doing this over the internet it seemed to take about as long as the original move of the library. It might not have taken as long since I just left it working overnight I didn’t know for sure.

Just remember, if you do plan on using the S3 for aperture not only are you paying for the space, which is very inexpensive, but you are also paying for each request for a file so it does add a few dollars each time you do a vault update. Overall I would still use it as a periodic off-site backup but would not rely upon it for my day-to-day backups.

Terminal Sweetness with reverse-i-search

I am a terminal n00b, but I’m liking it. I grew up on a M$ box and didn’t take the ‘leap’ to a linux / unix based operating system until about a year and a half ago when we got new computers at work. Since that time I have been trying to learn more about the terminal and am very impressed by it. I’ve been using OS X at work and Ubuntu at home and haven’t booted into windows (except for playing games) for almost a year.

Something that I found out in the recent months and finding very useful is the reverse-i-search. By pressing ctrl + r in the terminal (works at least in ubuntu and OS X, probably all real terminals) you are given a console line like the following:

(reverse-i-search)`':

As you type the terminal will search through your terminal history and locate any commands that contain what you search.

For instance if you type ssh it will start searching through the history and show you the last one that you used that had ssh in the command. If the first result isn’t the one that you are looking for you can press ctrl + r to keep the search going and cycle back through your history.

I am still amazed by all the things that I am learning about *nux operating systems and I am only touching the surface.