Package Dependencies in Java

Today I had one of those “oh, yeah, now I remember why I’ve been avoiding Java lately” moments. Over the last few months, when I’ve had time to code I’ve generally been using Ruby. Most recently I’ve been trying to pick up Scala and that means returning to the JVM. Since I happen to be working with an odd collection of technologies such as OSGi and Scala, things turned out to be doubly fun.

Setting up a build environment wasn’t too difficult. The Scala Eclipse plugin and the Eclipse PDE plugin conflict, (something I’m hoping to look into rectifying), so I had to start with an Ant build. Luckily, there is both a Scala Ant task and Peter Krien’s wonderful BND tool for generating OSGi bundles.

While the Ant build worked, it was hastily thrown together and I started considering Maven 2 or Rake. I ended up choosing Rake and I’m eyeing up adding Scala and OSGi support to buildr.

So far, so good. I had a basic “hello world” app using Rake, Scala and OSGi. Then I decided to grab another Java project from the Apache Incubator and start integrating that code into my project. That’s when things started to become interesting. It’s not really the project’s fault, so it’ll remain unnamed. It’s more a problem that there’s no good package management system for Java that spans both build and runtime.

Maven 2 does a decent job at sorting out dependencies during the build process. But that doesn’t necessarily help during runtime. If you’re collecting a series of libraries to run together, you have to track down their dependencies, and then their dependencies and then their dependencies… all hoping nothing conflicts. Some projects are nice enough to do this for you, but my question is, “Why don’t we have a platform that handles this automatically?”

OSGi lays the groundwork for this sort of solution. An OSGi bundle includes dependency information and package export information in its MANIFEST.MF file. This provides enough details for the OSGi container to construct a proper classpath, including handling different versions of different packages within the same container. But most Java libraries don’t include the necessarily manifest properties. (Consider this a plea—it’s simple to add OSGi properties to your Java library, it doesn’t hurt anything. Please do it.)

Honestly, why do I even need to specify any build or runtime dependencies unless I’m very interested in a specific implementation? I specify my dependencies in my Java import statements! That should be enough. If a Java repository contained OSGi package information, then the build tool could construct the necessary classpath without me specifying anything other than my import statements. If I had to, I could annote the versions in the source code or use a propertry file like BND requires. Then the system could likewise construct my classpath and launch in an OSGi container. Imagine that.

How is it that so many other platforms and languages have this figured out (CPAN, RubyGems, etc.) and Java is still in the stone age. Why don’t we have this yet???