JON 2.2 Released

April 29th, 2009

Congratulations to the JON team on the 2.2 release. Before moving to my current position on the Spacewalk team I spent two years on the JON team so it’s awesome for me to see the massive progress the product has made.

More information and screenshots at the JBoss.ORG Feed.

Descriptive Exceptions

April 27th, 2009

The exceptions lecture of the semester is one of the trickier ones I deal with. Part of the issue is that I try to cram it into a single class, a strategy that has backfired on me twice now. Another difficulty is the fact that while there is quite a bit of technical knowledge as far as throwing and catching exceptions, I could easily spend double that time covering design and best practices.

I took a bug today that covers the error messages shown to a user when they input an invalid channel name. Currently, we simply say “Invalid channel name” without any indication of why… was it too short, did it contain invalid characters, was it already in use, etc. Our name validation is correct, but from a user experience stand point, it could use a little love (this was exacerbated by the multi-org addition where a channel name could be taken without you being able to see that data otherwise).

There are a number of different validations we run against the name. A good sampling of them is found in the following snippet:

1
2
3
4
5
if (cname == null || 
    !Pattern.compile(CHANNEL_NAME_REGEX).matcher(cname).find() ||
    cname.length() < 6) {
        throw new InvalidChannelNameException();
    }

Again, the logic is fine. Any of the circumstances in the if clause represent an invalid name. But now we have the need to carry more information to better indicate why it failed.

I started by editing the exception class itself. The constructor now accepts two parameters. The first is the channel name; if we’re saying the exception represents an invalid channel name then it makes sense it should indicate exactly what was invalid. This also saves the UI some work in remembering what was specified that caused the error.

The second is an enum (defined as an inner class of the exception class itself) that describes the reason for the failure. The enum (currently – I’m kinda writing this as I work on it) looks like the following:

1
2
3
4
5
6
public enum Reason {
    REGEX_FAILS,
    TOO_SHORT,
    IS_MISSING,
    NAME_IN_USE
}

I’m a big fan of the enum for something like this. It’s clunky to make subclasses of InvalidChannelNameException just to indicate the different possible reasons for failure, and frankly a series of instanceof checks to later use that information would just be ugly. A similar if/else structure would be needed if I used a series of String constants stored in the exception’s message attribute.

Some camps would argue against the inner enum (is that the way to say an enum defined as an inner class?). Their reasons would center around the usage syntax. I actually feel the opposite way; the syntax I have to use since it’s defined as an inner enum reads really well in my opinion:

1
2
3
4
if (cname == null) {
    throw new InvalidChannelNameException(cname,
        InvalidChannelNameException.Reason.IS_MISSING);
}

Also realize that using an enum lets IntelliJ only show me the enum values when I get to that parameter. There’s no need to hunt around for the possible constants.

Once the extra information was in there, it was just a matter of getting the UI to display a custom message based on what actually happened, cleanly using a switch statement since I’m using enums.

1
2
3
4
5
6
7
8
9
10
11
12
catch (InvalidChannelNameException ferengi) {
    switch (ferengi.getReason()) {
        case IS_MISSING:
            errors.add(ActionMessages.GLOBAL_MESSAGE,
              new ActionMessage("edit.channel.invalidchannelname.missing"));
            break;
 
        case REGEX_FAILS:
            errors.add(ActionMessages.GLOBAL_MESSAGE,
              new ActionMessage("edit.channel.invalidchannelname.regex"));
            break;
[snip]

Again, IntelliJ can auto-complete here, this time only showing the possible values (i.e. the enum values) each time I start a new case clause.

1
2
// why can't I just pass in a dictionary? sigh, there are
// times where python would make this SOOOO much easier.

To give this some context, this was seen above a manual population of attributes in a bean from a map.

I don’t really have any witty comment on this one. There are definitely times where one language would be nicer than another, so I’m in no way saying the comment is incorrect in any way. It just usually makes me laugh to find conversational comments like this, as if you could actually hear the developer sigh when typing out the wordy bean copying.

Map Lookups

April 21st, 2009

Throughout the semester I have been enforcing the importance of overriding the equals/hashCode methods where applicable (i.e. domain objects). I just fixed a bug in Spacewalk that was caused by not implementing them, so I figured the real world example might help to illustrate my point.

For the record (not that I imagine people will find this all that interesting), the Bugzilla bug can be found here and the Spacewalk commit here. I’m sure everyone is just racing to read those over now.

I’ll try to keep the setup short. We have a map of capabilities and the key is an architecture type (ArchType). The ArchType class, however, didn’t implement equals/hashCode. So when the map was queried by the architecture type, it used the object reference as the key comparison.

There are some more details I’m not going to fully explain. In short, they are all pulled from the database but the instances themselves are potentially cached. So on the first request to the map, the queried type and the the type inside of the map happened to be the same object, so it pulled the result successfully. On subsequent tries however, the caching ended up causing the two instances to be different (despite containing the same data). In those cases, the results came back as null and we saw a really weird, almost non-deterministic error.

The fix was simple, override equals/hashCode in ArchType to use the data (in this case, the id) rather than allow the default comparison by object reference. So no matter how many times we recreate the ArchType objects from the database, it won’t be a problem since the key lookup will use the data inside of the objects, not their references.

Overriding equals and hashCode. Learn it. Live it. Love it.

Blowing off work

April 21st, 2009

I went downstairs to get more coffee and came back to find a substitute sitting in at work for me. Might as well put her to work.

Leanne Desk

This picture doesn’t do justice to the scenario, but she’s banging away at my second keyboard mounted under the desk.

Leanne Keyboard

New Site Theme

April 20th, 2009

Digg had a link to 40 Stylish, Minimal, and Clean Free Wordpress Themes. I started looking around and there were a few I liked. I tend to go in phases, and I’m currently in a bit of a “cram as much on the site as possible” phase, so I’m looking for something clean. I’m also in the mood for a dark background site, so I decided to give the Emire theme a shot.

One of the coolest parts about the themes (and the fact that I run the web server that hosts the site) is that I have access to the theme code to dork around with it. So immediately, I started hacking away at what I didn’t like. I gave myself a whopping 750px for the blog content, which is a very welcome change of real estate after a few iterations of claustrophobic themes.

The other big change was widget-izing the sidebar. I’m not sure why more themes don’t use Wordpress widgets. They’ve been around for a while, are very easy to use, and let me easily play around with the sidebar content from the Wordpress admin pages.

Add in some font changes and adopting the <pre> formatting from my old theme (which was originally stolen from zeusville in the first place… which I’m told came from Wordpress itself… and so on) and I’m at least happy enough to leave it like this for a bit. I’m not in love with having green again, so I might change around the secondary color, but I’ll let it sink in as it stands now before I go much further.

Let me know if there are any rendering issues, which would likely be due to me half-assedly flying around the theme code deleting stuff.

Triple-quoted Strings

April 20th, 2009

In Python, if you use three double quotes (I know, that just looks weird when written) you don’t have to escape newlines. For instance, I’m working with a query (it’s much longer, I cut out the middle):

1
2
3
4
5
6
7
8
9
10
11
12
_packageStatement_remove = """
    select distinct
        pn.name name,
        pe.epoch epoch,
        pe.version version,
        pe.release release,
        pa.label  arch
    from rhnActionPackage ap,
        rhnPackage p,
[snip]
        and ap.package_arch_id = pa.id(+)
        and p.id = cp.package_id"""

In Java, that’d be a lot uglier. I have no desire to convert the entire query, but it’d look something like:

1
2
3
4
5
6
7
8
String query = 
"select distinct " + 
"        pn.name name, " +
"        pe.epoch epoch, " +
"        pe.version version, " +
"        pe.release release, " +
"        pa.label  arch " +
[snip]

Also keep in mind that in most cases, you have to be careful to add the space after each line within the quotes. Otherwise, when Java munges this all into a single constant, you’ll get two words merged into one:

1
2
String foo = "golden" +
"monkey";

The contents of foo is simply "goldenmonkey" without any spaces. Needless to say, that can really screw with your query.

Score one for Python. :)