Tuesday, April 7, 2009

Another win for findbugs: is Math.abs broken?

I was wrapping up some code today, and ran into a weirdly interesting findbugs warning: RV_ABSOLUTE_VALUE_OF_HASHCODE.

Bill Pugh has a more in-depth post on his blog from 2006 about this. But, if you've ever written code like:

Object x = bucket[ Math.abs(y.hashCode()) % bucket.length]

you have a bug. Or, maybe it's a bug in Math.abs, depending on your point of view.

You would probably be surprised to learn that Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE, but it's true (go ahead and try it out).

So, about one time out of 4 billion, you'll get an ArrayIndexOutOfBoundsException, when your object's hashCode returns Integer.MIN_VALUE, and you end up with a negative array index.

This seems like a fairly common bit of code to write. In fact, back when Bill wrote this post, he uncovered this occurring 7 times in eclipse, 6 times in jboss, and twice in tomcat, among others.

This behavior sort of makes sense when you think about it. There's really no other value Math.abs could return for Integer.MIN_VALUE, and, it is, in fact, documented. Still, I'd bet that this bug exists somewhere in code you are using.

Anyway, it's worth reading Bill's post to check out some suggested fixes, and dig a little deeper into this.

Friday, April 3, 2009

stupid simple xml parsing

In the last few months, I've been doing a lot of XML parsing. It's been mostly small little parsers, in both java and python, trying to get some stats on different data sets. This is all on huge data sets, so streaming/stax type parsers. It's also kind of 3rd party data files, so of course the structure is crazy and weird :), or at least, I can't change it...

Anyway, last night I was working on probably my 5th or 6th parser, and man, was it getting repetitive. With these types of parsers, it's a lot of just keeping track of what state you're in, and then shoving it into your model.

Some pseudocode illustrating the repetitive nature of this:

case START_ELEMENT:
if (name == "company") { inCompany = true; }
if (name == "domains") { inDomains = true; }
if (name == "value" && inDomains) { inDomainValue = true; }
case CHARACTERS:
if (inDomainValue) { company.addDomain(characters) };
case END_ELEMENT:
if (name == "company") { inCompany = false; }
if (name == "domains" && inCompany) { inDomains = false; }
if (name == "value" && inDomain) { inDomainValue = false; }


Anyway, really repetitive... and just a pain to keep testing these similar parsers over and over again.

So, last night, I tried to come up with a super simple generic parser. In fact, I decided that all I really needed was some way to get the Strings I'm interested in into java objects. Initially, my model object had Integers, enums, sub objects. I decided that's too much -- No complex binding, just get the strings our of XML into java, and then from there I can form more complex objects if I need to, do filtering, etc.

I've also been wanted to take the time and learn more about java annotations. Of course, I've used them before, but I'd never created my own, or parsed them.

Here's the new model:

@XmlPath("company")
public class Company {
@XmlPath("name")
private String name;
@XmlPath("domains/value")
private List domains;
....
}


Now, you can just write

new SimpleParser(consumer, Company.class).parse(in);

The parser will inspect the Company class' annotations to figure out what paths it cares about, then internally keep a simple queue of its state. Each time it comes across a path the class cares about, it will either set the value, or add to the List of values depending on the field type. Again, only strings! Once it reaches the end element, it will pass off the last constructed to the consumer, then create a new bean.

Anyway, surprisingly, it worked pretty well! I realize this isn't going to solve all XML parsing needs, but it seems like for 90% of my use cases, it's "good enough."

I did a few searches, and didn't really find anything as simple, although StaXMate looks pretty interesting...

I'd love to get some feedback on this. I wonder if there's already something else out there? Or a better way to do this?

I put the code up on github, as stupid-xml. Quick warning: this is just a late night experiment. It's not production code. I did almost no checking of anything, there are no comments, it's probably crazy inefficient, and I'm probably doing a ton of dumb things. If so, please feel free to fork the code and submit changes, or send feedback, etc.

Monday, March 30, 2009

Exposing SVN version and build time with Ant

As a developer, I find that an application's most useful version number is its SVN version; once I have that number, I can head over to the repository and figure out exactly what code is running. This is extremely useful both during development (Did I upload the correct .war to my staging server?) and for ongoing maintenance (What version is running on this server that needs to be updated?)

Fortunately, it's pretty easy to configure Ant to automatically inject the SVN version into your application every time you build it. Let's say that you have a particular file (/WEB-INF/jsp/admin.jsp) that should contain the SVN version number.

We take advantage of svntask, a nice simple library that lets Ant use SVN. Download/unzip the project files, place them somewhere convenient in your project, and add the following to your Ant build file: (modifying the fileset directory to where you put the svntask libraries)
<target name="version">
<typedef resource="com/googlecode/svntask/svntask.xml">
<classpath>
<fileset dir="${lib.dir}/buildtime">
<include name="svnkit.jar" />
<include name="svntask.jar"/>
</fileset>
</classpath>
</typedef>

<svn>
<info path="." revisionProperty="revisionVersion" />
</svn>

<property name="svn.version" value="${revisionVersion}" />
</target>

This stores the SVN version number of your project root in the "svn.version" Ant property. Now, it's just a matter of copying the correct file from the source web directory to the target web directory before you package your .war file: (The following will require some modification depending on how you normally package your wars.) We use Ant's copy/filter tasks to replace all occurances of the token "@version@" in admin.jsp with the SVN version number.
<target name="war.pre" depends="version">
<copy file="${src.web.dir}/WEB-INF/jsp/admin.jsp"
tofile="${target.war.expanded.dir}/WEB-INF/jsp/admin.jsp"
overwrite="true">
<filterset>
<filter token="version" value="${svn.version}" />
</filterset>
</copy>
</target>

Now, the following snippit in admin.jsp
<div id="footer">
<p>Build Number @version@</p>
</div>

becomes
<div id="footer">
<p>Build Number 1692</p>
</div>

This is good enough for production releases, where the package application will (or should) be compiled straight from the repository. However, during development, I often won't be checking in changes between builds. So, to tell those builds apart, I find it useful to include the build timestamp as well, which I can get using Ant's tstamp task. This isn't a perfect solution, but it's enough to give me some reassurance that I didn't accidentally deploy an old build to my local server.
<target name="war.pre" depends="version">
<tstamp>
<format property="war.tstamp" pattern="yyyy-MM-dd HH:mm:ss z" />
</tstamp>
<copy file="${src.web.dir}/WEB-INF/jsp/admin.jsp"
tofile="${target.war.expanded.dir}/WEB-INF/jsp/admin.jsp"
overwrite="true">
<filterset>
<filter token="version" value="${svn.version}" />
<filter token="time" value="${war.tstamp}" />
</filterset>
</copy>
</target>

Now, inside of admin.jsp, I can include the following snippit
<div id="footer">
<p>Build Number @version@ (@time@)</p>
</div>

and Ant will transform this into
<div id="footer">
<p>Build Number 1692 (2009-03-30 11:20:15 PDT)</p>
</div>

which is exactly what I want.

Wednesday, March 25, 2009

Dude. Sweet.

Larry tipped me off to the new AWS Toolkit for Eclipse. This looks like it could be pretty awesome for integrating/viewing our EC2 instances.

Friday, March 20, 2009

super lightweight cms

We wanted to roll something out that would allow us to update some areas of our site more easily, and make the content a little more dynamic. Specifically, the News and Announcements page and the Behind the Scenes page.

We've all had experiences with big crazy cms solutions, that do a million things, none of them all that well, and never exactly what you want.

Also, we're a really small team, so we didn't want to set something up that would require a lot of maintenance, or even require a new service or machine.

For "Behind the Scenes", we're already using twitter for company updates. I think this is a great solution for posting short news items, or links, for any site.

The next step was to integrate with Flickr for our Around the office photos. We set up a public, invite only Bizo group. Anyone at Bizo can post photos to this group, and they'll show up on our site. Flickr handles the authentication/authorization, content storage and hosting, and a decent API for getting content on the site.

For "News and Announcements", we wanted a way to be able to easily update any news or press releases, quickly, and without requiring a site release.

We ended up creating a simple blogspot blog to host the content. Blogs/RSS seemed like a pretty close fit. You already have the concept of multiple published items, with dates, titles, and content. Using the excellent rome java library, we pull the content in on the backend, do a little content parsing, then render the results.

The "content parsing" is a little hacky. We wanted slightly more structure around our entries than you get from an RSS feed. So, we expect all of the posts to be formatted like "image (optional), text, read more link". Blogger lets you set up Post Templates, so, it's actually not that bad. When you go "super lightweight", you have to expect to make some tradeoffs, and this seemed like one worth making.

The other nice thing about externalizing your content like this is that you can start pulling it into other places. Last night we launched a new version of our homepage with a flash ticker, that pulls in these news items from the same place.

So there you go: a free, lightweight, zero infrastructure CMS recipe.

Thursday, February 26, 2009

Contradictions

So I've got a need to do some work in Rails. Since I've not really used it before, I decided to go through the nice tutorial at Rubyonrails.org. I'm running merrily along when:

% rake db:create
Rails requires RubyGems >= 1.3.1 (you have 1.2.0). Please `gem update --system` and try again.


Okay, fine. I try it...

% sudo gem update --system
Updating RubyGems
Nothing to update


Huh. Really?

I found this helpful tidbit about updating RubyGems on Mac OS X.

% sudo gem install rubygems-update
Successfully installed rubygems-update-1.3.1
1 gem installed
% sudo update_rubygems
Installing RubyGems 1.3.1
[... a bunch of stuff ...]
------------------------------------------------------------------------------
RubyGems installed the following executables:
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/gem

If `gem` was installed by a previous RubyGems installation, you may need
to remove it by hand.


Well, that definitely looks more promising!

% gem --version
1.3.1

Sweet.

Tuesday, February 17, 2009

java keyword challenge

Found this C++ coding exercise on twitter this morning: Write a standards-conforming C++ program containing a sequence of at least ten different consecutive keywords not separated by identifiers, operators, punctutation characters, etc.

Pretty fun read.

I thought it would be interesting to try and come up with something similar in Java. It seems like I'm constantly adding "final" everywhere, so it can't be that hard, right?

Here's the list of the Java Language Keywords.

Unfortunately, in Java, we don't have anything we can repeat, like sizeof. Also, some of the java keywords require non-keyword tokens ({, }) to be used (do, while), where their c++ equivalents do not.

Anyway, let's give it a shot:

private static transient volatile boolean
b;
private static transient final boolean
b2 = true;

5 sequential keywords in a member declaration.

Okay, method declarations:

public static synchronized final native void a();
public static synchronized final strictfp void b() { }

I can't say I've ever used native or strictfp, but that gets us to 6 sequential keywords.

There aren't as many sequential keywords we can use for class declarations:

private static final class c { }
private abstract static class d { }

That's only 4 sequential keywords.

So 6 sequential java keywords. That's my max. Can anyone do better?