Java Again
After a decade, I’m coding for the VM again
In 2001—after working for years on the Java server platform—I left Sun to explore the world outside the virtual machine. I dabbled with Python, trudged through some C, and even played with such odd things as XML Query. Then, building native applications on Mac OS X captured my imagination. That lead me into an exploration of Cocoa, first with Java and then with Objective-C, the language which powered it.
With its pointers, header files, and a syntax that reflects its heritage of being first implemented as pre-processor to the C compiler, using ObjC was like rolling back the clock to a prehistoric age. On the other hand, its object-orientation was much closer to Smalltalk than anything else I’d worked with before and—ironically given both the age of ObjC and Smalltalk—it felt like something from the future. Despite its warts, I found myself enjoying it. I often described it as having all the brute force of a chain saw with the finesse of a scalpel. A lovely mix.
After a few more years, I started working on server applications again using another dynamically typed language: Ruby. Despite its frustrating support for Unicode which has only recently been sorted out, it’s rather tepid concurrency abilities, and the rather middling performance of its default runtime, the leverage Ruby gives a programmer to quickly explore a problem and define a solution is amazing. It quickly became the default tool in my programming bag.
From then on, I was sold. In fact, I didn’t expect that I’d ever work in a statically typed language again—and certainly not Java which felt like it was firmly behind me.
Imagine my surprise, then, after signing up with 6Wunderkinder this year to work on Wunderlist, one of the things I was asked to do was to shake the rust off my Java skills. I’m not going to lie to you. After years of using languages and environments that I thought were better in one way or another, the first few months of working in Java again hurt my brain. It didn’t help that I was doing so under the pressure of starting the first full time job I’d had in over a decade mixed with a desire to be immediately helpful and productive.
I had to look up the names of methods, learn how to put semicolons at the end of my lines again, and sort out dealing with fussy build environments again. All very awkward when you walk in the door with a reputation as that guy who created Tomcat and Ant. I had to explain more than once that it’d been a really long time and oops, sorry, yah, I did just make that rookie mistake.
I felt a bit like a fighter coming out of retirement. Every day at the office was painful as I used out-of-practice muscles again. Every night, I went home mentally exhausted. But, every morning brought obvious improvement. Entire chapters of my programming experience came out of cold storage. I’d finish one day trying to remember how to deal with threading effectively on the VM and wake up the next morning mentally sorting out ways work around the limitations of Java’s concurrency mechanisms—one of my own many personal “I know Judo!” moments over the last few months.
As I’ve come back to form, I’ve had the chance to revisit a lot of assumptions that I’ve built up over the years about Java. For example, I’ve been fascinated to re-evaluate my stance about static typing. I thought that I was a convert to the ways of dynamic types, never to come back again. With generics and parameterized types, however, along with a healthy use of reflection when appropriate, I’m mostly getting along just fine again with Java’s type system. The only real issue I have with it at this point is all the redundant, well, typing you have to do. There are simply too many lines that end up looking something like:
Something something = SomethingFactory.something(somethingConfig);
Another assumption I’ve carried all these years is that Java seems to have a propensity to lead programmers to an insane amount of verboseness, over-documentation, and—for lack of a better word—Baroqueness. Cargo cult programming abounds. While it’s easy to write a big ball of mud in any language, Java seems especially fertile for it.
I don’t have any way to back this up, but I have a gut feeling that the very powerful IDEs that most Java programmers lean on to help them craft their code also let them indulge the worst of their bad angels. Instead of encouraging tight and elegant code, they seem to promote ever-growing densely incomprehensible codebases that sprawl out so much that they become impossible to comprehend and navigate without that very IDE.
To challenge this feeling, I used Android Studio and then the full version of IntelliJ for over a month. While the tools are very capable, I felt a bit like I was driving an SUV with the kind of super-soft power steering which removes all road feel. Comfortable, but maybe too comfortable—like the comfort that tempts you to sleep when you’re driving down a wide-open highway.
One day—almost without realizing it—I went back to the lightweight toolset I’ve used for most projects since I worked at JavaSoft: a decent text editor and the command line. It worked well for me then. It still does today.
At conferences in the early to mid-2000s, I would frequently quip that Java was the Cobol of the 21st Century. That always got a reaction. Of course, I did partially mean it as the barb it sounds like. It takes a lot of boilerplate to do simple things in Java. But, I also meant it as acknowledgement of Java’s dominance and usefulness in many fields, including finance. Java might have become boring, but it was usefully boring. Not a bad thing, really.
A decade later, Java—especially the language—is as still boringly relevant as ever where it built up traction. And, truth be told, I’m still not eager to jump back into those spaces. Despite the small role I played helping to define it, Java EE is meant for building a different kind of application than I ever was interested in.
Surprisingly enough, however, there is excitement happening in places outside of Java’s traditional stronghold. Languages like Clojure and Scala unlock functional programming with robust concurrency models on the VM and their REPL consoles bring the same kind of ability to poke at code that Ruby’s irb gives. And, while they are statically typed, their language doesn’t smack you in the face with a blunt hammer with it. Frameworks like Akka and Play bring a whole new way to think about and build scalable applications. It’s all an energizing breath of fresh air.
Another thing I used to say in public gatherings—especially after somebody inevitably gave me shit for using XML as a build file format—was that I would be more than happy to see the tool that would replace Ant. I thought Gradle might be it, but in my experience the last few months, it’s been a lot more fussy than I’d like. Scala’s sbt, on the other hand, is turning out to be much more my speed. The moment I built and installed my first Android app written in Scala onto my Nexus over a USB cable from the command line instead of using an IDE, well, that was pretty eye opening.
If you’d told me a year ago that I’d be working with Java again and enjoying it, I’d have laughed at you. Or just snorted and looked at you strangely. Even now, I’m rather surprised at the whole idea. More surprising is the enthusiasm with which I find myself checking what’s available on the VM.
Maybe it’s a case of playing with new and shiny things. Maybe in a few months, I’ll be deep into Go. Who knows. One thing for sure, when I contemplate the next bit of code I want to write, Ruby isn’t necessarily the first language I think of anymore. And that comes as quite the surprise.