Dependencies Redux
By Adrian Sutton
I ranted earlier about dependencies and the way Java programmers are always pining for the latest and greatest. The comment by Stephen Thorne to the article deserves being published with the same level of visibility as the original post so I quote it below. It also deserves some rebuttal which is also below.
I’ve been saying this for years, and yet I still run into rabid pro-java programmers who managed to rattle off a list of reasons why java is the bestest programming language in the world include “good library support” to which my response is “hold on, slow down, good library support? let me tell you a story…” and I recite any one of a dozen anecdotes about dependancy hell in java. The only java project I’ve seen that manages to avoid this without extreme pain is kowari, which takes the slant “We’ll distribute the ENTIRE DAMNED THING as a .jar, libraries included, just make sure you have a recent enough JVM.” They don’t have the windowing troubles because its a database. ;) The first thing I want to correct is the implication that java doesn’t have good library support – it absolutely does. Look around at the huge range of libraries available for Java and particularly look at the fantastic standard library that comes with it. Plenty of top quality libraries for pretty much every moderately common task. There is however a separate issue of dependency management. Problematic dependency management (aka dll hell) is caused by two things:
- Poor or non-existent dependency management tools.
- Large range of libraries and version incompatibilities. If you don’t have both of those, you won’t get dependency problems. The fact that Java has great library support actually leads to dependency problems because there are more libraries to choose from and most of those libraries are rapidly improving. The standard libraries in the JRE don’t generally suffer from dependency problems because they are incredibly good at providing backwards compatibility and because there are good tools for managing versions. The trouble is people write code that’s based on assumptions rather than specifications (ie: they were lucky it worked on any version so they shouldn’t complain that it breaks on a different version), and because people don’t take advantage of the version management tools that are available for the JRE. That’s the crux of my rant, if people put some effort into their software, you should wind up in dependency hell at least as far as the standard JRE is concerned. People just don’t aim high enough. Version management for libraries that aren’t in the JRE is pretty much non-existent in the Java world however there are some very important options that are available and are severely underused. These options control the classpath. Most Java developers know that they can “set” the classpath with the -classpath option and that’s a good start. However what they don’t know is that the -classpath option is the last place searched for class files. The first place is the boot classpath (including for simplicity sake the endorsed library paths), and it can be specified using the -Xbootclasspath option and it’s variants (hint: you almost always want to use the /a or /p variants). After that the standard extensions directories are searched and this is where most conflicts come in. Don’t put stuff in here, you don’t need to. Let me repeat that, don’t put stuff in here, you don’t need to. It will come back and bite you later if you do put stuff in there. (To be fair there are a couple of exceptions to this, for instance Apple installs Java3D and QuickTime for Java into the standard extensions directory which makes sense, however application developers shouldn’t do it because their apps are not system wide and thus shouldn’t affect the entire system.) The simple form of this advice is: use Java WebStart. It’s extremely good at managing dependencies, including native libraries that your application might need. As an added bonus it gives you automatic application updates and a double clickable application icon (an application bundle on OS X, entry in the Gnome menu under Gnome and a shortcut on the desktop and in the start menu on Windows) for free. Finally, in response to the comment:
“We’ll distribute the ENTIRE DAMNED THING as a .jar, libraries included, just make sure you have a recent enough JVM.” I suggest you look around a little more. For instance, the range of Ephox products detect the libraries you require and download them as needed as well as automatically installing or updating the JVM if required. Further to this we support any JVM from Java 1.3 and above. Then take a look at Fluidium. If you already have Java installed, just click here and it should install all it’s required dependencies and run. A little bit of JavaScript and I could get the JVM to auto install as well (though that wouldn’t play well when sent off to the blog aggregators). Note that Fluidium isn’t a pure Java application – it actually installs native libraries and links itself to them automatically and seamlessly. The downside of native libraries is that it may not actually have a version of the library for your particular platform. Now consider how many other programs you’ve installed and run simply by clicking on a link, waiting for it to download and clicking through a security dialog. Cool stuff and entirely possible to do with any language, not just Java. The problem is, people aren’t putting enough effort into making their applications really easy to deploy and that was what I was complaining about. I now have two points to make:
- Take the time to make your software easy to deploy. It is important and it’s not done often enough.
- The language used is much less important than you think. Great programs can be written in any language and any language can be used to write awful programs.