Why Java hates you and your family

Posted:

Programmers love to argue about which programming languages are better than others. If you listen carefully, you’ll notice that there’s a hierarchy to the debate. Java programmers laugh at C++. C++ coders deride C monkeys. Everyone laughs at shell hackers. No one can understand assembly programmers and those that “think in LISP” occupy a sublime and knowing orbit above all rest (so they think).

But I’m a Perl hacker first and foremost. Despite some of the more vocal members of the community, Perl is a humble language (with, as its critics will quickly add, much to be humble about). In recent years, I’ve forced myself out of this comfort zone into the wider world of programming. Like all generalist, I try to pick the right tool for the task. For instance, PHP is a best tool I’ve found for general web applications, which is why this site uses it. For quick and dirty Windows games, Python (with its pygame library bindings to SDL) stands alone. For repetative system admin tasks, shell scripts and cron combine like Voltron to create superlative software robots. The thing is, most programming languages are pretty similar. They have data types, loops and conditional branching.
That’s really the bare minimum you need to get things done. Where languages differ is in the services they offer the programmer.

I’ve heard that you love someone not for his winning attributes, but for his faults. However, I’ve found that there are definitely some faults that are harder to love than others. This missive is about those faults in Java that keep our relationship forever at the stage of the first date. If Java is your “Main Mama”, you may want to stop reading this now.

For my work, I need to hack up a bit of Java that speaks XML-RPC. Now, you may recall that I’m no stranger to working with this protocol. I’ve written XML-RPC clients and servers in Python, Perl, PHP, ASP and even (God help me) C. But I missed out on Java until now.

No problem, I thought. I’ll just look through my book at the chapter Simon St. Laurent wrote about using the helma XML-RPC library for Java. Simon did the lion’s share of the book and did the most thorough job of any of us on the project, so I took a look. Funny thing: that library has morphed into the Apache XML-RPC library. Ok, fine.
How different could it be? I mean, it was working fine before. How many changes were needed? Perl’s Frontier::RPC library has hardly changed in six years (and we use it heavily at Leostream).

As it turns out, the one thing Java does well is faciliate abstractions. With the newest version of the library, you can tweak all kinds of parameters, swap out XML parsers, add additional data types (which defeats the whole effing point of XML-RPC), create new class factories — the list goes on! In fact, there’s a whole class just for configuring the XML-RPC client! Excessive you say? Just wait.

The one thing you can’t do with this library is start using it quickly. The main culprit? Missing dependencies. When I tried to run a simple XML-RPC client, it complained about not knowning how to encode the XML-RPC timestamp thingie. Oy. But wait! Weren’t JAR files
supposed to solve this issue? Wrong again, Fatty!

Ok, so I needed to install subversion just to get the bleeding-edge version of the missing ws-common library. That’s not so bad, right? Wrong. I also needed to get a nightly snapshot of the TRUNK code of the main library because the “release” version could not handle structures correctly (the unknown “string” problem). Fine. That happens. It’s open source so you’ve got to expect the release management to get a little “cowboy” sometimes.

At length, my “hello, world” XML-RPC program got up and running. After several phone calls gloating about this teapot triumph, I proceeded on to handling more realistic and complicated data structures. I had my test server return a structure to my Java client that had a value that was an array.
In perl, the structure looks something like this:

  { "foo" => "bar",
    "boz" => [ "boom", "doom", "soon" ],
  }

Here’s a quick test: how many dictionary classes does Java have? I’m talking about generic collection types that hold key-value pairs. 1? 3? 10? Wrong!
It’s a trick question. In Java, new Map classes spontaneously generate all the time.

I bring this up because in order to traverse this data structure, I need to know the how to type the objects correctly. Now, in simple programs where you control the data, that’s easy. When you have to deal with arbitrary data coming in from an unknown source, Java whips out the hate on you.

Because Java sucks is very advanced, I have to iterate through methods to transverse this structure. Something like the following:

Map my_struct = get_the_struct();

Iterator it = struct.keySet().iterator();
while (it.hasNext()) {
  Object this_key = my_struct.next();
  Object raw_object = result.get(this_key);

   // here comes the good part
   Class c = raw_object.getClass();
   if (c.isArray()) {
       // fetching this object was so nice, I do it twice!
       Object [] this_value = (Object []) result.get(this_key);
       System.out.print(this_key + " => ");
       int i;
       for (i=0; i < this_value.length; i++ ) {
           System.out.print(this_value[i] + ", ");
       }
       System.out.println();
   } else {
     // simple data type
     System.out.println(this_key + " => " + raw_object);
   }
}

It took me about 3 hours to puzzle out this code. It would have been swell for the docs to have an example of handling complex data like arrays and hashes, but then I would have missed out on my afternoon of personal discovery and emotional growth.

After many fruitless web, book, and source code searches, I managed to hack this code to handle my “weird” data. It’s crappy, but it works.

The truly loathesome part is the way I had to work with hash values that are arrays. For reasons that aren’t clear, I couldn’t just use the value returned from a Map if it is an array of Objects. That would be too easy. I had to properly cast the data because Java is a bucket full of venomous hate. Of course, I need to check if the object is, in fact, an array and then fetch the object again for the cast!

Allow me to paint with a very broad brush for a moment. The stunt programming exhibited in the code above is exactly the kind of stupidity that prevents Java folks from learning about what’s going on in the rest of the computer universe. Strict data typing is 100%, no-foolin’ legalese.

All modern scripting languages handle this kind of “collection of random data types” better than Java. VBScript is only slightly less lawyerly about it, but it too sucks hard on big, stiff data structures (VBScript has two assignment operators: one for objects, one for everything else. Thanks for nothing, Microsoft).

It’s enough to really bring me down, man.

What the hell is wrong with these language designers? Can they please stop worrying about continuations, anonymous classes, multiple inheritance, abstract interfaces, factory classes and orthogonality long enough to make a language that’s useful for the kind of problems I have to deal with? I live in world of strings. If your language makes dealing with strings hard for me, I will hate you with my fists.

Can I get a “hell ya!”?

Jesus H. Christ.