Let’s talk about Java and keeping the damn kids of the lawn…

I found this gem mixed in with some old Java code of mine. There is nothing inherently wrong with this class by itself and I bet each and every one of you has a copy of exactly the same class somewhere in your Java code base. In fact, you probably have 8 or 10 different versions of this basic abstraction scattered throughout different projects. I know I do – this is just one of them:

/*
* Created on Apr 15, 2004
*/packageio;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;/**
* Creates an easy to use input interface.
* Abstracts all the stream related operations.
*
* @author Lukasz Grzegorz Maciak
*
*/publicclass Input
{privateBufferedReader in;/**
* in will read from the Standard.in using BufferedReader.
*
*/public Input(){
in =newBufferedReader(newInputStreamReader(System.in));}/**
* At any time, the input source can be changed to another
* BufferedReader. This can be used to read commands
* from batch files and etc.
*
* @param i a BufferedReader object
*/publicvoid setInput(BufferedReader i){
in = i;}/**
* Restores the input to the default (System.in)
*
*/publicvoid restoreDefaultInput(){
in =newBufferedReader(newInputStreamReader(System.in));}/**
* Reads a line from the input stream. It returns a string so
* if you plan on reading numbers or other data types you need
* to parse it yourself
*
* @return a String representation of that line
* @throws IOException if there was an IO error
*/publicString readln()throwsIOException{return in.readLine();}}

Why did I write this back in 2004? Because I was sick and tired of plugging the following line in each class that needed to read user input from the console:

Some input classes used to be more elaborate including parsing logic letting you ask the user specifically for an integer or a float, or something like that. It’s a nice touch but not essential. What we all really needed back then was a simple console input class but Java mysteriously didn’t provide any. I still remember how the instructors would react when we asked how do you do cin in Java. They would wince, scratch their head and say we will cover that next semester, and for now we should just use the keyboard.java class that came with the book.

Actually, no I lied – my Java instructor didn’t wince or scratch his head. He stuck out his tongue, and scratched his chin for a while. The tongue thing was sort of a thermal valve release thing I think – he did that whenever he was asked a difficult question that required some thought. I guess his brain was prone to overheating – or maybe it was just covered with a thick layer of dust due to lack of use. Then after a 3 minutes of intensive processing (I think his brain was clocked at 1Hz tops) he finally responded that he doesn’t know about “sea-ins but it is probably in the book”. Which was really his default answer – I was always curious why it always took him so long to retrieve the “it is in the book” reply. We theorized that his brain had almost no RAM so if you interrupted his train of thought he was pagefaulting and fetching from storage.

But yes, real teachers made us use some kind of custom written version of the class above until we knew enough about streams to write our own. Every book had a different implementation, with different quirks and dependencies. They were all bloated, and buggy and they ended up being hacked and modified and passed around from student to student. It was a mess – and teaching the language was an interesting exercise of hard waving away all the boilerplate code, class declarations and import statements.

It took Sun close to 10 years to finally provide a simple and easy to use console input class. Now, ever since Java 6 came out back in Dec 2006 we can simply do:

String foo =System.console().readLine();

Why was this not part of the language from the get go? It was not some sort of implementation difficulty or backward compatibility problem. The root of the problem was purely philosophical – in Java input was done with streams, and wrapping one or two stream readers around System.in was deemed perfectly acceptable. That is the thing about Java’s design – whenever there was a choice between straightforward, consistent approach and overly verbose and convoluted one, Sun has always picked the later rather than the former. For example, for the longest time the language did not have a printf function. Instead of passing in an argument formated in a specific way, you had to initialize the NimberFormater class then run 3 or 4 methods on that instance before you could print the string again. So the code that now (since 1.5) can be expressed as:

Naturally, you could still use NumberFormat if you wanted to. Sometimes it might be more appropriate especially if you are planning to extend it. But in most cases you really do not need to touch it.

Note that printf is not really syntactical sugar – it is abstraction. Same with the console class – it hides some of the implementation details from the programmer for a good reason. The less code you see on the screen, the easier it becomes to understand. While that NumberFormat block above is very straightforward, if you encountered it in some larger project you probably wouldn’t know what it does at a glance. You would have to mentally step through it line by line to actually figure out you are just fiddling with decimal number precision here. Abstraction is not always about hiding the low level stuff – it is sometimes about hiding the high level stuff that is just to long, and unwieldy to read.

Java is inherently verbose – it’s tendency to replace short and sweet syntactical sugar with long class declarations, and multi level initializations combines with it’s hefty dose of boilerplate (that just must be there) and static typing declarations to compound the problem. It is actually not uncommon to see a 5 lines of pseudo code in the comments, that are then implemented in over 60 lines of actual Java.

And there is a high probability that those 60 lines are in fact abstracting some weird Java quirk – something that ought to be done at the language design level. But instead everyone ends up with their own version of some trivial functionality. And each programmer brings his own utils package which contains among other things the tweaked out keyboard.java and their own implementation of printf. It is especially fun when you try to merge two projects and you realize that they both contain 300 lines of code that implement exactly the same thing but differently, and that refactoring this stuff won’t be that easy as each system relies on the funny little quirks of those custom classes that implement rather trivial functionality.

This is why most of us hack in Eclipse instead of vi – because you need an industrial strength tractor to haul these mountains of code. This is probably also one of the reasons why educators pick BlueJay as the introductory Java IDE, which I think is actually a harmful practice.

It seems to me that Java is currently in the process of joining the league of “old folks” languages that people tend to respect, and emulate in certain ways but not actually use or get excited about. C and C++ are permanent members of that club already. Every time someone brings up one of these languages, the senior programmers usually get that nostalgic feeling – remember those silly pointers, and the link errors – these were the times. The junior programmers usually roll their eyes and mutter something about thankfully not having a pleasure to experience the doubtful joy of manual memory management. Java is slowly but surely heading in that direction.

Java? Heh, I used to use it all the time. I remember that my hello world program was like 7 pages long. It used to make you feel productive – at the end of the day you would realize you wrote few hundred lines of code that don’t really do anything yet – they just need to be there.

Yup… We are getting there. This is one of the reasons why when I was asked to develop web applications I immediately attached myself to PHP. Ruby was not around back then so my choice was essentially between JSP, ASP (booo Microsoft) and PHP. PHP is not very elegant, or very structured. It really takes after it’s cousin perl in that it looks like shit, but gets the job done. And this is what I needed. I needed to build applications quickly, and be able to adapt them to the the constantly changing specs, not spend time modeling, initializing static types and writing essays in code. PHP was language that allowed me to do stuff without much of a hassle.

Note that this was years ago when I was still an impressionable young Java guy. I totally loved the language – and I had a blast designing and modeling my code. I always had this impeccable class hierarchy, organized in packages, all with javadoc comments. It was great – most of the programming assignments were absolutely trivial to me (especially when I was undergrad) so I would amuse myself by beautifying my code, adding functionality it didn’t need and etc. Each of my projects was essentially a thick novel sized stack of papers and my peers would look at me in horror and dismay. I loved it. But to actually do work in Java? Even back then, I decided that to be productive and effective I needed something else.

Java has changed since then – but not a lot. In fact there seems to be a very strong opposition to change in the Java camp. Hell, we wouldn’t have generics, un-boxing and the foreach loop if it wasn’t for C#. The Java ripoff from Microsoft has somehow became a thorn in the side of the Java developers to the point where it motivated them to add features and niceties we were asking for for years. So things are slowly improving. We might even get closures in the next release. Or not – it might be to radical of a step for them. Maybe we will never get them. Then there is a question if we really need them? Why would I even want to wait for Java to implement closures. If I needed them, I could always code in Javascript, and then compile it into Java compatibile bytecode using rhino.

In other words, I can route around Java limitations and verbosity by using another JVM compatible language. This is why we have scala, and jruby and jython and groovy and bunch of other things like that. The java platform slowly growing into a language agnostic platform of it’s own whether sun wants it or not.

Java is no longer the new, cool or hip thing it was when I was starting college. Back then it was huge improvement over C++. It really made our lives easier, and let us be more productive. It was always a hulking behemoth, but we hardly noticed by then because C was a beast that had tormented us for years on its own. But we have moved past that. No one is excited about Java anymore. When I say Java, I see people rolling their eyes and wincing the same way we rolled our eyes and winced when listening about C++.

Java is now entering that “older, wiser and more mature but totally uncool” status. It is not getting retired yet – it’s definitely not senile, and surely not ready for the old-folks home. It’s just getting to that point in it’s life when it starts to tuck in it’s shirt, pull up it’s pants all the way up past the waistline, and has a suddenly discovers some deep seethed desire to keep the damn kids of it’s lawn.

And it seems that no matter how many features they add Java will be still overly verbose, still statically typed and still huge and unwieldy. Naturally, no one is going to drop support for it anytime soon. But given a choice people will be making the same judgment call as I did few years ago and will jump ship. But nowadays they don’t really have to jump far. They don’t even need to leave the Java ecosystem. All they have to do is to switch to one of the other JVM based languages.

First, we have Rhino and Javascript which Steve Yegge predicts to be the Next Big Language. It already has closures, it is dynamically typed, and much more expressive and readable than Java. And yet it lets you leverage the power of the whole Java API. In fact it is fully bytecode compatibile with Java which means you can easily mix and match pure Java and Rhino classes. In fact, once you compile it, there is virtually no difference between the two. Granted, people are not flocking to this one yet but that’s probably because of the “Javascript is for the web” stigma. But with some clever branding we could really get some momentum behind this one.

Ten there is Scala which I keep hearing about. It’s gaining momentum really fast and hype is building up. I really haven’t used it for anything so I can’t say much about it. The website claims it can tap into the .NET CLR libraries in addition to being bytecode compatible with Java which seems to be quite impressive.

We also have stuff like JRuby and Jython which are bound to gain prominence as the youngsters who grew hacking in Ruby and Python get absorbed by the huge Java infrastructures working in the business world. The point is that we can write Java without actually writing Java if we wanted to.

Lately I have been working almost exclusively in PHP, Python and Javascript. I’m also messing around with Ruby and Lisp on the side. Last time I have touched Java was when I wrote code for my thesis and i haven’t touched it since then. It just doesn’t seem as much fun as it used to be. Perhaps I have changed and I’m no longer content just modeling stuff and writing novel sized applications witch don’t really do all that much. It is still my primary language – one that I probably understand the best. But as I’m picking up new projects, and doing new things, time and time again I choose not to use Java as there are always more flexible and exciting tools for the job at hand.

Actually, the idea of a VM is not bad. Look at Microsoft and .NET – they also use the same concept. You compile into a bytecode which is then executed on a virtual machine. They need to run on exactly one OS but they still picked this way of doing things. There are more languages which work this way. Java sucks not because it runs on multiple platforms though but for entirely different reasons – some of which I mentioned above.

Your email address will not be published. Required fields are marked *

Comment

Notify me of followup comments via e-mail

Name *

Email *

Website

Currently you have JavaScript disabled. In order to post comments, please make sure JavaScript and Cookies are enabled, and reload the page.Click here for instructions on how to enable JavaScript in your browser.