Java Annotations – Java’s love of configuration over convention

March 11th, 2009

In the beginning, EJB was a bloated mess of XML configuration files that allowed some sort of ultimate flexibility that absolutely no one needed nor cared about. And it sucked. So developers started using conventions to keep track of the four classes required to make a remote method call, and XDoclet was created to automate the creation of the XML configuration files. And it sucked less. Following in EJB’s footsteps, Hibernate did the same thing. And XDoclet followed. And it still sucked.

So, annotations were created to essentially formalize what XDoclet was doing, instead of considering how horribly broken the implementation of J2EE or Hibernate was. And now that we have annotations, the “implementation pattern” of “ultimate flexibility through annotations” has made its way into numerous Java frameworks, such as JAX-RS and JPA.

Regarding JPA:

@Id
@GeneratedValue
@Column(name="person_id")
public int getPersonId() { return personId; }

This is not a significant improvement over XDoclet; the only benefit is if you mistype “GeneratedValue”, the compiler will catch it. I shouldn’t have to type “GeneratedValue” in the first place. Unless I’m doing something non-standard. Which I almost never do.

I have a Person class with a getPersonId method. Can JPA just assume that it maps to the PERSON table, and the PERSON_ID, respectively. Further, couldn’t it figure out that it’s the auto-generated primary key since the schema says primary key auto increment. All the information is there and available to the framework to figure this out.

The same goes for EJB. I have a class named FooStatelessBean. How about we assume it’s a stateless session bean, and it’s interface is defined by its public methods? It can then provide FooRemote and FooLocal for me, and I don’t need to configure anything or keep three classes in sync.

Just because Java doesn’t have all the Ruby dynamic magic doesn’t mean we can’t make things easy. In reading Surya Suravarapu’s blog post about CRUD via JAX-RS I can’t help wondering why it takes so much code to call a few methods on a class?

Did the designers of JAX-RS not even look at how Rails does things? I get a PUT to the url /customers/45. We should default to calling put(45) on the class CustomersResource. Only if I want to obfuscate what’s going (e.g. by having FooBar.frobnosticate() handle the request) should I be required to provide configuration.

Even in Surya’s example code, he’s following some conventions: His resource class is suffixed with Resource and his POST method is prefixed add. This should be baked into the spec. It’s like EJB all over again with the common conventions that aren’t supported by the framework because of too much useless flexibilty.

Supporting convention over configuration is easy in Java. In just a few hours, I had a tiny web framework that proves it1. It wouldn’t take much more effort to allow the default behavior to be overridden, but, unlike JAX-RS, EJB, or even the Servlet spec itself, it doesn’t punish developers who follow conventions. It makes their lives easier and thus encourages good behavior.

So, the point of all this is that annotations encourage bad framework design; unnecessary configuration is a major part of many Java frameworks and specs. And I have no idea why.


1it unfortunately breaks down at the UI layer, due to a statically typed and compiled language not being a great choice for implementing web UIs, but that’s another issue.

Git, GitHub, forking: the new hotness

February 5th, 2009

While working on my Gliffy Ruby Client, I decided I wanted a better way to describe the command line interface. Finding nothing that was any good, I whipped up GLI and refactored my Giffy command line client to use it. While doing that, I finally got annoyed at technoweenie’s version of rest-client, and also noticed that the original author’s had totally changed interfaces. So, clicked the nice “Fork” button on GitHub to get my own copy and fixed the issues. But that’s not the cool part. The cool part is that I can change my Gliffy gem to depend on my rest-client implementation and, viola! No special instructions, no hacks, no nothing. This is a really cool thing that would be difficult with Subversion, impossible without RubyGems, and downright painful without GitHub.

Execute on your ideas now; forget secrecy, forget tweaking

January 22nd, 2009

A couple interesting things happened yesterday. I attended my company’s annual meeting and watched the season premiere of Lost. At my company’s annual meeting, we went over lots of exciting things, but there was some concern over our use of Google Apps for our email. Mainly, that they could glean our IP from reading our email and, should they choose to enter our market, gain an unfair advantage. Meanwhile on Lost, the writers actually gave us some insight into the time-travel elements of the show, describing several aspects of time travel that are not typically used in your average time-travel story. So, what have these two things to do with each other?

I’d been noodling with a short story centered around time travel, and the type of time travel I was going to explore is very similar to what was described on Lost. Close enough that my story would come off as a bit less original than it would have 3 months ago. Even if my idea isn’t that original (which ones really are?) it’s a bit frustrating to see your idea developed (and deployed) by someone else independently.

So, again, what have these to do with each other? They demonstrate the reality of (and difference between) coming up with an idea and actually doing something with it. Essentially, and idea, in and of itself, is not particularly valuable. It’s what you do with it that really counts. If Google were to steal my company’s IP by sniffing our email, I doubt it would have much effect on our ultimate success. Outside of stealing our code or data outright, our idea isn’t something that’s hard to come up with. We just happened to come up with it and execute on it first. Anyone getting into the game now is necessarily behind us. Could someone lap us? Certainly. Is their ability to do so in any way dependent on know our secret ideas? I seriously doubt it.

So, sitting on ideas is a waste of time. Trying to hide an idea either for security or for fear of “unleashing” it in an underdeveloped state is counter-productive. Someone else has your idea. Guaranteed. And it’s likely they are developing it. So, you should be developing it too, and hopefully releasing it to the world, rather than worry about who’s stealing it, or who came up with it first. The first to market reaps the rewards.

Command line interface for Gliffy

January 14th, 2009

My command line interface for Gliffy is relatively complete. It works pretty well, though the error handling isn’t very clean. It’s written in Ruby (RDoc here) and can be used as a Ruby client for Gliffy.

I decided on Ruby since that would be the most fun and didn’t require learning a new programming language. I initially tried to make an ActiveRecord-style domain-based interface, but it was just too difficult and it was hard to see the real benefit. At the end of the day, I think integrating Gliffy into another application is a relatively simple thing, and a procedural interface would probably be the easiest way to do that. So, I modeled it after the PHP client library, more or less.

The command line interface uses the Ruby client library and provides just the basic functions I need:

> gliffy ls
321654 Some Diagram
987654 Some Other Diagram
> gliffy edit 321654
# Takes you to your browser to edit the diagram

I live on the command line, so this is much more expedient than logging into Gliffy and navigating the UI to edit a diagram.

I’m already feeling like providing access to the folders via the command line would be helpful (they are exposed in the Ruby client of course). Not sure how much the API will ultimately change (it’s in private beta now), but hopefully not too much.

GitHub does it again; another killer feature

December 18th, 2008

GitHub Pages (explained here) is yet another awesome feature of GitHub. You can publish, via git, arbitrary web content (even piping it through Jekyll for Textile markup and syntax highlighting). They have been keeping a tremendous momentum of late; introducing new features on a regular basis. I hope they keep it up. GitHub is, IMO, crushing SourceForge and Google Code in terms of simplicity, ease-of-use, and overall functionality.

Gliffy API private beta: what should I do?

December 12th, 2008

Gliffy hooked me up with access to the private beta of their API (which I helped design and implement). I create a PHP client and experimental MediaWiki plugin to validate the API while working for them, and now I want to get something else going in my spare time.

My first thought was to make a Ruby client, because I think it would be fun and relatively easy. But, I have to admit that a Wordpress plugin would be more useful to me personally. That being said, A Trac extension would be useful at work, since we are using Trac (which is python based, and I can’t say I’m too interestedin Python at the moment). I think if GitHub allowed git access to project wikis, it would be cool to allow easier integration of Gliffy diagrams to GitHub project wikis.

At any rate, I don’t have tons of time outside of work, so I want it to be something easily achievable, and also something Chris and Clint are not likely to work on themselves….

Why underscores might be better than camel case

December 10th, 2008

So, the “Ruby way” is to use underscores to delimit most identifiers, e.g. “add_months_to_date“, as opposed to the Java camel-case way of “addMonthsToDate“. This was initially something that irked me about Ruby, mostly because typing an underscore is kindof a pain (shift with the left hand and pinky with the other).

Now that I’ve started working, I’ve been reading a lot of code and realizing that code is more often read than written. Ultimately, camel case is a just lot harder to read (especially if you create meaningful method names like myself and my co-workers seem to do).

It’s pretty hard to defend:

Date calculatePersonDataUsageHistoryStartDate() {}

as more readable than:

def calculate_person_data_usage_history_start_date()
end

The underscores are like spaces, making the identifier a lot more readable. Of course, both are more readable than:

// Calculates the start date of the
// person's data usage history
time_ prsn_dt_uhst_st_dt(){}

This would never fly with Java (and, honestly, look a bit weird), but I’m no longer gonna curse the Ruby convention.

Gliffy updated their site!

December 9th, 2008

Though I’m no longer working for Gliffy, I’m excited to see that they updated their site with some of what I worked on! Awesome!

Specifically, I worked on the folder organization system that they added to replace the tagging system. This fell out of the API work that I did (which I’m assuming is in private beta right now, but I’m not sure). I also worked on a feature that, while painful as a developer, is my favorite new thing about Gliffy: the basic account no longer has a five-diagram limit! That means for free, you can create unlimited diagrams. The catch is that your diagrams are all public, but I think it’s a great way to enhance the functionality while subversively getting their name out to more people.

EMMA and TestNG for Simple Java Code Coverage

December 7th, 2008

Although RCov makes code coverage in Ruby dead simple, I wasn’t sure how easy this would be to achieve with Java. The first free tool I found is called EMMA and it was surprisingly easy to setup, especially since the documentation isn’t geared toward getting coverage during tests (but getting it during execution).

EMMA works by instrumenting the classfiles to analyze coverage. Although it can do just-in-time instrumentation, that didn’t seem to work for recording coverage via TestNG. The offline instrumentation makes is pretty easy to use with anything. Basically, you want your ANT file to:

  1. Compile your code
  2. Use EMMA to instrument your classes to a different directory
  3. Run your tests, using the instrumented classes first in your classpath
  4. and passing a few system properties to your running code

  5. Run EMMA’s report generator on the output

At first, I was getting some runtime errors because interfaces are not instrumented (and don’t show up in the location you tell EMMA to put them). The solution is to put both your instrumented classes directory and your regular, non-instrumented classes directory in the classpath, making sure the instrumented ones are first.

Here’s my test.xml I’m using in my fork of ImportScrubber that shows it all working together. All in all, it only took about 15 minutes to set up and debug. Of course, now, the tests that came with ImportScrubber provide almost no coverage, but that’s another story….

I can haz job

December 1st, 2008

So, I am finally employed and I didn’t even have to settle. After a refreshingly protracted and detailed interview process, I’m finally schlepping myself to a job that I’m more or less excited about. That’s saying something, since I’ve spent the last 8 months at home (6.5 of them working for Gliffy) in my perfect environment: waking up whenever, using my dual-monitor mac, Rudy close by. My first day was a net win, despite having to bring in my own computer, and overall I’m not complaining because I get to use a Mac at work thank GOD.

Pluses so far:

  • Smart people I can have a conversation with
  • Meaningful product (i.e. not another CRUD app for a government agency [not that there's anything wrong with it])
  • Not only have they heard of javadoc, they use it!
  • Database migrations!
  • Clean looking code and tests that actually pass on a fresh checkout!
  • No M$ exchange server or other shitbox mail system (they use Google Apps)
  • Damn close to home; I should be biking in real soon
  • Relaxed environment
  • I’m one person away from a bonafide window with the shades open!

Honestly, it’s almost a 100% on my interview rubric (which I took down for a while, because some HR person read it and gave me shit about not liking having a dress code. I mean, does anyone really like putting on a suit and tie to site and write code? Or to do anything? We’re talking levels of tolerance, and mine is low, mostly because I believe dress codes indicate a deeper organizational problem of priority management).

Negatives so far:

  • Kinda noisy office (fortunately few people seem to have phones)
  • Subversion (it looks like they aren’t going nuts with branches, so git-svn should preserve my sanity in this regard)

On the fence so far:

  • Maven – The only reason this isn’t a negative is that it’s better than the pile of shit ant script everyone else uses, and the build does work pretty painlessly.
  • Spring – I haven’t used Spring for anything real, and I can’t say it gets me excited (nor have I ever thought it sounded all that great), but I’m optimistic about it. I figure if it, in fact, is great, I’m happy. If it sucks, I have fodder for ranting. It’s a win/win. I do fear the XML situps tho.