Tech startups are sexy. They evoke a certain romantic charm that you usually find attached to wild west outlaws, fighter pilots, and Rambo. They represent the dream shared by so many software engineers who find that their career trajectory has flattened out and who want to ditch the cubicle and change the world. To the experienced developer slogging his way through yet another stack of enterprise reporting requirements, it seems like he’s somehow missing out on the action.

In fact, engineers at startups do have quite a bit in common with Rambo, sans the chiseled physique. We are the action heros of the tech community. We’re idolized by our cube-dwelling enterprise counterparts and get to live on the bleeding edge of software development. But just as Rambo has to tough it out alone in the wilderness, we startup engineers have to survive in some extreme conditions. It’s a rough life, and it’s not for everyone. So, I’m going to tell you why you shouldn’t work at a startup, why you might want to, and let you decide. If you still want to work at one, we’re hiring.

Why You Shouldn’t

  1. You’ll be exposed.

    In larger teams, you benefit from the safety of the herd. At a startup, there is no such protection. Every line of code you write will be brutally evaluated for its contribution to the business. You can’t point fingers because you might well be the only engineer on the team.

  2. You will work long hours.

    Well-established companies have had time to refine their processes. They also tend to move more slowly and operate on longer schedules. In a startup, the business will be burning through someone’s personal nest egg in order to pay salaries. Breaking any promise made to a customer or investor amounts to suicide for the company , so all-nighters are not out of the question.

  3. You’ll be paid less (cash).

    “Will you work for stock?” Expect to be asked this dreaded and clichéd question. Despite the horror stories you hear about engineers slaving away for months only to have the business fail and “getting screwed” by the founders, the investment community these days expects a full-time, equity-holding technical founder. Every single dollar matters at this point, so if you’re looking for a luxurious salary or great benefits early on, startups are not for you.

  4. You’ll wear multiple hats.

    I’m a software engineer, but in my startup I’m also a graphic artist, copywriter, salesperson, HR manager, tester, support technician, and the janitor. If the founders have their heads screwed on straight, they will try as hard as they can not to distract a nerd in the zone, but if you want to show up at 9am, code uninterrupted all day, and leave at 5pm, startups might not be for you.

  5. Nothing you build will be sacred.

    The Pivot is all the rage these days. A huge percentage of successful startups end up altering their business model more than once along the way. This usually means that you will throw away code, and you’ll do so often. The entire point of a startup is to experiment with different business ideas until a) one wins or b) the money runs out. You can be guaranteed that the money will run out if you don’t have the courage to change gears when the market tells you to. You have to check your pride at the door.

Why You Should

  1. We might just change the world.

    Startups, by definition, are searching for a repeatable and scalable business model. We could be chasing after wild geese, but some few of us will grow to become the next big thing in technology. Successful startups often create entirely new markets out of thin air, or shatter the foundations of established industry.

  2. We get to play with the latest tech.

    Startups exist to experiment. Almost everything we build is a greenfield project. When you’re building something totally new, you have the opportunity to try out technology that’s “not tested” enough for the enterprise.

  3. Simple office politics

    If the company succeeds, this simple life won’t last forever but, during the lean-and-mean phase, office drama doesn’t show up too much. As an example, if you get on a roll and end up coding until 3am on a sweet feature, nobody is going to give you grief for showing up at 11am. You usually won’t have to put up with intraoffice romance and you’ll tend to get along great with your coworkers.

  4. You’ll get to stretch your wings

    The amount of responsibility you carry in a startup is great. There is no one to cover for your mistakes, but this can be viewed as a good thing. You will be given the opportunity to try out just about any idea you come up with. You might get the opportunity to manage a small team for the first time. You usually can’t get in this in a larger company, as roles are more clearly-defined and job stereotypes tend to be more rigid.

  5. You get in “on the ground floor”

    This should honestly be the last reason you choose to join a startup, but it is a valid reason. Strictly by the numbers, you will likely end up ahead by taking the high salary at a larger company and investing it wisely in public markets. However if the company succeeds, and you’ve shared in the risk, there’s a good chance of a nice payoff.

  6. Bragging Rights.

    As I said earlier, tech startups are sexy. For your inner narcissist, this might be reason enough to get into the game.

Some say there’s an angel / venture-capital bubble happening now. In Q4 of 2010, VCs invested $72 million into startups in the tech hotbed of my home state, Boulder. If you still want to ditch that grey cubicle, tear your shirt off, and strike out into the wildness with nothing but a knife, now might just be a great time to join a startup.

Note: As with everything I write, I choose to use the masculine pronouns “he/his/him” to refer to gender-neutral singular contexts. I can’t stand the “singular they” and I won’t clutter my prose with “he/she” simply to avoid being called a misogynist. It takes a lot more to qualify for that label than a mere choice of pronoun.

 

UPDATE:
There is now a much easier way of dong this. (Many thanks to Deluan Quintão)


Working with applications on multiple versions of Grails can be a pain. First you have to set your GRAILS_HOME environment variable, and then you have to make sure that the grails shell script (or grails.bat) is in your path. Since I have to switch versions frequently, I whipped up a simple shell script to make this easy. This is *nix specific (and may even be bash-specific), but it works for me.

Usage

$ ./setGrailsVersion 1.3.2
$ grails
Welcome to Grails 1.3.2 - http://grails.org/
Licensed under Apache Standard License 2.0
.......

$ ./setGrailsVersion 1.2.2
$ grails
Welcome to Grails 1.2.2 - http://grails.org/
Licensed under Apache Standard License 2.0
.......

Prerequisites:

  • Unzip your versions of grails side-by-side in a known directory. I use ~/grailsBase, so a valid install would be ~/grailsBase/grails-1.3.2
  • Leave your GRAILS_HOME environment variable set to ~/grailsBase/grails
  • Leave your PATH environment variable with an entry to ~/grailsBase/grails/bin
  • Save this script along side your installs. For me, this means I save it at ~/grailsBase/setGrailsVersion.sh

Script:

#!/bin/sh

##
## Switches grails versions by changing the the symlink ~/grails to a
## ~/grails-$VERSION
##
## Author: Dan Lynn (dan@danlynn.com)
##

if [ -z "$1" ]; then
	cat <<End-of-message
Usage:
	$0 [version]

The version argument must be a valid grails installation and comes in the standard grails versioning scheme.

Examples:
	$0 1.3.2
	$0 1.2.2

End-of-message

	exit 1
fi

DIRNAME=`dirname "$0"`
NEW_GRAILS_HOME="$DIRNAME/grails-$1"

if [ ! -d $NEW_GRAILS_HOME ]; then
	echo "$NEW_GRAILS_HOME doesn't exist!" >&2
	exit 1
fi

rm "$DIRNAME/grails"
ln -s $NEW_GRAILS_HOME "$DIRNAME/grails"
 

I am excited about Cloud Foundry. It promises to greatly simplify java application deployment to Amazon’s Elastic Compute Cloud (EC2). With a few clicks, you can deploy an J2EE application (e.g. Grails) to the container of your choice (Tomcat 5.5tc Server, and more) on a fresh EC2 Linux instance backed by a MySQL database on Amazon’s Elastic Block Store (EBS). It doesn’t get much easier than this. The instance configuration automatically configures your container behind an Apache instance, which gives you some great options for hosting static content or configuring side-by-side application platforms.

I’ve been using Burt Beckwith‘s UI Performance plugin for Grails to bundle and compress my static content (images, js, css) during the build, so I can save on outbound bandwith and improve the response time of my application. In order to take advantage of this build-time optimization, we need to modify the Apache configuration to serve static content instead of proxying those requests to the container.

  1. $ grails install-plugin ui-performance
  2. Configure your app to use the plugin’s taglibs and to bundle resources if necessary. (See http://www.grails.org/plugin/ui-performance)
  3. Add a handler for the CreateWarEnd event in your scripts/Events.groovy file (make one if you don’t have one). This handler will package all the bundled and gzipped resources into a static zip file that you can upload to Cloud Foundry:
    eventCreateWarEnd = {warName, stagingDir ->
        def directory = new File(warName).parent
    
        ant.zip(destfile:"${directory}/static.zip") {
            fileset(dir:"${stagingDir}") {
                include name: "images/**"
                include name: "css/**"
                include name: "js/**"
            }
        }
    }
    
  4. Create a “container initialization script” for Cloud Foundry to execute when your instance starts up. This script will tell Apache to directly serve the following directories and to add the appropriate Content-Encoding header for content that is already gzipped. The name doesn’t really matter at this point, but I called mine proxyexcludes.sh.
    cat > /etc/httpd/conf.d/_proxyexcludes.conf <<END
    ProxyPass /images !
    ProxyPass /css !
    ProxyPass /js !
    
    SetEnvIf Request_URI "\\.gz\\.(css|js|jpg|gif|png|ico)\$" already_compressed=true
    Header set Content-Encoding gzip env=already_compressed
    END
    

    I found that keeping this file up to date was easier if I just let grails rebuild it every time after the WAR is created. I modified my eventCreateWarEnd handler to take care of this for me:

    eventCreateWarEnd = {warName, stagingDir ->
        def directory = new File(warName).parent
    
        ant.zip(destfile:"${directory}/static.zip") {
            fileset(dir:"${stagingDir}") {
                include name: "images/**"
                include name: "css/**"
                include name: "js/**"
            }
        }
    
        ant.echo "Creating Proxy exclusion list: ${directory}/proxyexcludes.sh"
        new File("${directory}/proxyexcludes.sh") << """cat > /etc/httpd/conf.d/_proxyexcludes.conf <<END
    ProxyPass /images !
    ProxyPass /css !
    ProxyPass /js !
    
    SetEnvIf Request_URI "\\.gz\\.(css|js|jpg|gif|png|ico)\$" already_compressed=true
    Header set Content-Encoding gzip env=already_compressed
    END
    """
    
    }
    
  5. $ grails war
  6. Upload the static.zip file produced during the build as “static content” when you upload your app to Cloud Foundry:

    Cloud Foundry Upload Static Content

  7. When creating a deployment, upload your “proxyexcludes.sh” container initialization script:

    Cloud Foundry Deployment

  8. Fire up your instance and check out the performance gains!
Tagged with:
 

Back in 2007, I found myself doing a lot of classic ASP work in VBScript. For anyone who has had to endure this, I created a library to help you out (released under the MIT open source license). Since classic ASP runs under Microsoft Active Scripting, this means you can write ASP pages in page in any supported scripting language; I’ve even gotten Python working under classic ASP.  The library allows you to use a more functional programming idiom on the server-side, thanks the Prototype library and JScript, a supported scripting language. I’ve merely reposted my original version, but I plan to update it to the latest version of the Prototype library and move the code to either GitHub or Google Code. Until then, give it a shot.

Tagged with:
 

Several retailers have signed up for Visa’s Verified by Visa program, which adds an additional step to the familiar online credit card process. Theoretically, this step makes the transaction more secure by allowing you to specify and use a password in addition to the usual details like “name on card” and “billing address”. Unfortunately their password requirements are terrible. Passwords must contain at least 6 characters and at most 8 characters, must contain at least one letter and at least one number and no special characters allowed.

Here is their javascript password validator:


if( (/\W/).test(document.passwdForm.pin1.value) || (document.passwdForm.pin1.value.length < 6) || (document.passwdForm.pin1.value.length > 8 ) )
{
    alert("Your password does not conform to the Password Policy. Please try again.");
    document.passwdForm.pin1.focus();
    return false;
}

For a feature that supposedly exists to protect my money on the web, this is just pathetic.

 

Not wanting to drive outside of the city at 2 AM, I figured I’d try to catch one or two meteors from The Leonids from my backyard. Sadly, all I got was a pretty indigo sky and some nice looking stars. Until next time…

No Leonids for Littleton

No Leonids for Littleton

In a grails application, I needed to persist a complicated expression tree to the database, but I didn’t want to have Hibernate generate a database table for the information as it would greatly affect read performance (lots of joins) and I don’t need to have relational access to subsets of the tree. I decided to serialize the entire tree into a BLOB.

After creating a Hibernate userType to handle the serialization/deserialization, I ran into a ClassNotFoundException when attempting to deserialize my object.  I found out that this is due to java using the “last defined ClassLoader” when deserializing with an ObjectInputStream, which might not be the right ClassLoader in a Groovy environment (see: http://jira.codehaus.org/browse/GROOVY-1627.

The solution? Subclass ObjectInputStream to allow you to pass in a predefined ClassLoader and override the resolveClass(ObjectStream classDesc) to use this ClassLoader parameter:


public class ClassLoaderAwareObjectInputStream extends ObjectInputStream {

 private ClassLoader myClassLoader;

 public ClassLoaderAwareObjectInputStream(ClassLoader myClassLoader) throws IOException, SecurityException {
 super();
 this.myClassLoader = myClassLoader;
 }

 public ClassLoaderAwareObjectInputStream(InputStream in, ClassLoader myClassLoader) throws IOException {
 super(in);
 this.myClassLoader = myClassLoader;
 }

 @Override
 protected Class resolveClass(ObjectStreamClass desc) throws IOException,
 ClassNotFoundException {
 String name = desc.getName();
 return Class.forName(name, false, myClassLoader);
 }
}

Thanks to Satish Gunnu for the tip.

Tagged with:
 
Automatic Updates automatically restarts your computer for you

Automatic Updates automatically restarts your computer for you

 

Let’s say that you’ve decided you want to add a globally-unique identifier (GUID/UUID) to one of your domain classes. You might want to do this for portability to other systems or for a variety of reasons. Given that some people in the Grails community don’t recommend using a UUID or string as a primary key, you might find that you want to add a UUID as a separate natural key to your class and set it using GORM’s beforeInsert event hook:

class Person {
    String name
    String uniqueIdentifier

    transient beforeInsert = {
        uniqueIdentifier = java.util.UUID.randomUUID().toString()
    }
}

This works great, but if you’re like me, in that you like to work with test data while developing, you probably have some code in your BootStrap.groovy file that no longer works. The problem is that GORM’s validate() method does not call event hooks, and that property we just added is not nullable. One small change and we’re back in business:

class Person {
    String name
    String uniqueIdentifier

    stating constraints = {
        uniqueIdentifier(nullable:true)
    }

    transient beforeInsert = {
        uniqueIdentifier = java.util.UUID.randomUUID().toString()
    }
}
 

We just recently moved our continuous integration server to new hardware and removed a costly database comparison step, which shortened our build time from 10 minutes to less than 3. Half the time is spent on unit tests, and we include a build versioning step which prepares every build for potential release.

Cutting those seven minutes out of the feedback loop may not seem like much, but when you consider that we average about 20 builds per day that’s significant savings, even if there were only one developer waiting on the build results each time. Next up: database versioning using liquibase.

Tagged with: