Many Java vendors and developers seem slightly mystified as to why Java hasn’t taken over the software landscape as completely as was originally promised and expected. They just can’t understand why people are still writing and running various dialects of C and other platform-dependent languages - surely it’s supposed to be “Run Anywhere, All Java, All The Time”?
However, it’s pretty obvious to anyone who has actually had to use Java programs why they’re not as popular as they might otherwise be.
The platform dependence of ol’ fashioned binaries is an advantage as well as a disadvantage. Platforms usually include library management infrastructure; standard library sets, standard paths, built-in runtime paths that you an override, system-wide configuration tools and dynamic linkers. Therefore, when you type ./program, you don’t need to worry about where the SSL libraries are or how to tell it to find libz. (I’m leaving out the arguments about DLL hell and why you can’t install a GNOME application without installing a chain of six dependent libraries and updating a further ten.)
Java, being new and “platform-independent”, does not yet have these facilities. There are competing implementations of some libraries, such as XML parsers - better make sure you have the right ones. There are no standard places to put them and nothing to manage them. These factors explain why packaged applications typically include copies of the required libraries, until your system is awash with multiple versions of the Xalan lib.
Worse, you have to explicitly tell Java where to find the required libraries (of classes) via the CLASSPATH environment variable or -classpath command line argument, because the application itself contains no clues. The elements in the class path can either be directories that contain expanded class hierarchies or JAR files, which are the same hierarchies archived into a ZIP file. (In fact, you can use ZIP files too; the JARs just have a couple of unnecessary housekeeping files added. You can even put the application classes in a JAR and use java -jar <jarfile> to run it.) Note that it can’t include directories containing several JAR files, which would go some way towards obviating the imminent pain (whereas by analogy, the Unix dynamic linker library path lists only directories holding shared library archive files).
Hence for a Java application that uses several libraries, the class path will look something like: /foo/bar/moo.jar:/burble/farble/wibble/oink.jar: /zip/pity/doo/dah/quack.jar:… …and so on for lines and lines. By the way, make sure you get them in the right order. Anything less will produce the dreaded “ClassNotFound” exception (with no indication of which library the class is in). You could, of course, avoid all this by simply bundling the library classes in with the application ones (effectively a form of static linking, a concept that the serious Unix vendors have been trying to kill off for years), but that would be as crazy as bundling your own dedicated Java Runtime Environment…erm, oops.
And when you get that right, you also have to know - and type - the fully qualified name of the entry or initial class. That’s “know”, not “discover”. C programs have these too, but they’re always called main() by convention so the compiler automatically makes that the entry point.
Realising that most users rapidly grow tired of typing in lines like this and debugging class location errors, Java programmers usually supply a wrapper script or batch file to encapsulate the necessary environment settings and startup command. They have to write several such scripts, one for each platform that the “platform-independent” application will run on (oops). And unfortunately, in my experience, Java programmers suck at scripting. Perhaps they’ve been mollycoddled by all that Object Orientation. Abstracting duplicated data, particularly path prefixes, into variables is apparently an arcane mystery to them. Even passing through command line arguments is often too much effort (in fact, I’ve seen scripts that - after a tortured fashion - implement a fairly normal command line syntax and munge it into whatever bizarre form their Java app expects; why not just write the app to parse proper arguments in the first place, people?). Indentation and formatting? Forget it. (Well, you only need one level of indentation when you avoid the complicated stuff.) Process management? Wha’??
Finally, of course, you have to package all this crud up into some form that can be installed and managed as a single entity…erm nope, haven’t quite cracked that one yet.
That’s why your Java app is such a pain to start (and stop), let alone relocate. In fact, I’ve seen major name applications that are started by running a script in the background, after which it hangs around like an unwanted parent at a school disco.
Sun have recently attempted to alleviate some of this pain with a technology called WebStart, which offers online downloads and updates of packaged Java apps and their libraries. The programmer has to write the spec file for this packaging to describe the dependent libraries and Java versioning, which is at it should be. WebStart insists that all Java files are signed cryptographically - here’s where it falls down, thanks to Java Man’s disconnect with the real world. The key management tools are moderately easy to use (and to abuse when you’re in a hurry and you don’t have time for all this signing crap). Moderate because you have to sign everything in the package with the same key, once only. Mismatched or multiple certs will cause the install to fail. Probably wise, but rather annoying when the various JARs are coming from several different sources and may occasionally be updated. Never mind, the security this offers is laughable anyway…because when you enter your passphrase for the key, it appears on your terminal in clear text. Ten years of fighting bad password management and someone on the “cutting edge” makes a boneheaded, simple mistake like that!
…And you wonder why users seem to lack faith in Java applications. (Look! I wrote this article and didn’t even mention the performance, the ugly GUI toolkits, the resource overhead and all the usual canards.)