Sunday, February 27, 2011

I moved to a new team more than half a year ago and at first things were rough. The team itself was fine but I was giving up my precious C# for Java and I was entering a whole universe of new software. My technology stack changed from Microsoft branded IDEs to that of the open source crowd. I was out of my element but I thought, "Hey, time to try something new!".

Let's just get this out of the way; as a language, Java is not aging well. Certainly not in comparison to C# which is getting updated more frequently with a lot better language niceties. When .NET rev'ed itself up to v3 it brought along lambdas and extension methods which makes for some really nice, clean code. This is noticeably absent from Java. Even the simple act of passing around functions is no where to be seen in Java. I have to create a full-blown class that implements one method. It feels like Java is more worried about being pulled from the holy scripture of Design Patterns than it is about making a language that is enjoyable. Ah, you can pass an anonymous class but it's still waaaay too verbose.

But that's the thing with Java. It seems like it tries to be as horrifically verbose as possible. One of the common Java practices is to mark everything final. You see final everywhere. Final member variables, final arguments, final variable declaration, final classes, final final final. You'd wish that they marked things NON-final because there are far fewer instances of that. Better yet, choose a language where variables are immutable by default. You end up with a lot of chatty code, which is unfortunate since it's already a static language...you don't want to be known for pushing the envelope on verbosity. Here's my favorite quote about it,

Whenever I write code in Java I feel like I'm filling out endless forms in triplicate.

-- Joe Marshall

I can forgive these sins because I've finally been exposed to open source software. Software built by the community. For us, by us. Open source software has a distinctly different flavor to Microsoft software. Tools load faster. There's less fluff. It's more of what you need and less of what you don't need. If something has a bug, it's fixed quickly and you can get the patch as soon as someone posts it. You don't have to live with the same crap for years because it just doesn't show up as a priority on Microsoft's radar. You know, like the "add reference dialog" that has been the bane of our existence since early 2000 that they only recently addressed (sort of).

I was introduced to Maven which is build and dependency management for Java. For anyone who cares about build automation (and that had better be ALL of you), Maven beats the ever living snot out of anything you can find in .NET. .NET's build automation story is absolutely abysmal in comparison. I know some people think Maven is kinda crappy but it's still light years beyond what the .NET crowd has going on. The only thing that seems to be standardized in .NET is using NAnt (and possibly but incredibly doubtfully, Albacore/Rake). Here's a simple scenario that is more difficult to do in .NET,

Gather dependencies

Compile code

Run Unit tests

Run Integration tests

Deploy the application

Run smoke tests

Step 1 was always something that was custom to whatever shop you worked at. This is where someone had to copy third party libraries somewhere your build process could access them (probably a lame network share). This is a problem that has been solved for years with things like the Maven repository in Java and Gems repository in Ruby. Maven just does this out of the box. When you run a build, it will retrieve your dependencies prior to compilation. There's a project NuGet for .NET that is supposed to alleviate this problem and I admit I haven't tried using it. I can only hope it gets integrated into another project like Maven for the .NET community.

Steps 2-3 are straight forward (and usually) don't introduce too much pain. Step 4 usually requires partially constructing the environment of your application which includes databases, web applications and other such "heavy" dependencies. This is where the open source community trounces .NET. When I tried automating testing of web applications it required that IIS be installed, that I had the correct users/authentication, that I figure out the mystery of the Web Deploy tools that are anything but intuitive and extremely prejudiced to IIS 6, blah blah blah. It was a process that required massive manual intervention and implementation. It's brittle and no company wants to pay for the time it would take to implement that.

With Maven, I just reference the Tomcat web server plugin, tell it to start a web application on the fly, install it, and run it. It's disgustingly simple to do and it's actually running a very good analog of my production environment. You don't get Tomcat Home Edition or Tomcat Developer Edition or some other lame neutered version of the web server product (I'm looking at you Cassini web server). You get the real deal and you get it with only a handful of XML declarations.

Step 5 in .NET has no real public support or method. It sucks. Using the same Maven Tomcat plugin I mentioned above, deploying your web application is a breeze.

I don't think I care to carry on describing how immature the state of build automation is in .NET. Suffice it to say, we .NET devs should stop waiting for Microsoft to make it for us. It's a glacial development. There's too much to be learned from the open source software projects. First lesson, not all .NET projects need to be monetized. Yes, you can be compensated for your hard work but there are tons of opportunities to do that outside of selling a product. Embrace your community, have them push the feature list. We can go from there.

So while I get a lot better developer tools in open source software, it doesn't come without a price. I'm not impressed with documentation and it's difficult to find the answers you need. Unless you subscribe to their IRC channel or mailing list, you aren't going to find help from available online content. Sure, it can get you going but once the rubber meets the road you will inevitably hit an issue that doesn't seem to be covered in anything you can find with conventional Google searches. I've come to loathe all the websites that index mailing lists, jira and java documentation only to provide you with advertisement-laden dead ends. You'll have to subscribe to a mailing list, post your question and pray that somebody wants to respond to a question they've probably seen a dozen times before.

The open source world isn't perfect but I love the tooling and the low barrier for entry. If you've been living in the .NET bubble for some time, take a break and try something new. The worst case is that you recognize ways to make your life easier.

I find it interesting to hear people's perspective that have gotten a chance to try various platforms. I've been firmly in the Java camp for ages, plus a little dabbling with Ruby on Rails. I wish I had some of those schnazzy features in C#, but I've apparently been taking my build tools for granted. By the way, Maven holds a place in the Java community that is either derided or praised. People love it or hate it. I'm not a hater... but the seeds of its future are being planted in things like Gradle (haven't used it).

@jim it's good I waited to reflect on my experiences because I would have done a lot more complaining about Java and I hadn't yet seen the awesome stuff it has in the open source software.

@david I see the same thing about Maven but, for me, it's a step up so I'll need another couple months before I can start taking it for granted ;) Gradle, Buildr, Rake, etc. seem to be the way implementing build automation is moving. If we've learned anything about programming in XML (or XML in general) is that it sucks. Having a first class language to write build automation with seems long overdue.