Take a common technology stack for a JEE application, it could contain these major dependencies:
These dependencies easily comes out of hand. The most common solution I see applied out there, is something in the lines of, taking the most recent version of the jars in conflict and hoping it works.
Another problem is that the dependencies between jars are not explicit. There is no standard way for a jar file to express a dependency on another jar file in a given version. Today, we need each individual project to document their dependencies. More often than not, this is not done and jar file dependencies distributed with a library, often have file names without versions.
.Net solved this
In the .Net platform, assemblies are the jars of .Net and all assemblies contain both their own version and the names and versions of other assemblies, that it depends upon. The CLR is responsible for using this information at execution-/load-time to locate the depended upon assemblies, in correct versions, and link them together.
To be able to do this, there are some important aspects of the .Net platform itself:
- A standard, system-wide place to deploy assemblies (the Global Assembly Cache, GAC)
- Version of assembly as a part of the assembly file format itself
- Version and names of depended upon assemblies as part of the assembly file format itself
- Code in the CLR (the VM of .Net) that makes use of this information
<?xml version ="1.0"?>
<assemblyIdentity name="foo-assembly" culture="" publicKeyToken="83d83231a2fe9534"/>
<bindingRedirect oldVersion="22.214.171.124" newVersion="126.96.36.199"/>
This file will force the CLR version used to v2.0.50727 (and fail execution of not available), and redirect the dependency on v188.8.131.52 of foo-assembly to v184.108.40.206 of same assembly.
JSR-277 might come to rescue
Finally, someone has seen the need for this on the Java platform too. JSR-277: "Java Module System", seems to aim at solving this stuff. What JSR-277 will provide is:
- A new distribution format called a Java Module, which will contain metadata, both about what the module itself contains, but also about which dependencies code in the module has.
- A standardized versioning scheme
- A repository for storing, discovering and retrieving modules
- Runtime support in application launcher and class loader for using the module metadata
It looks like the JSR has taken a lot of its ideas from OSGi. For instance the idea of explicitly exporting which parts of the module, that can be depended upon from other modules. Actually, this opens up for a nice feature, as the JVM can hide internal dependencies from other modules, in effect making different versions of the same jar file possible in the same application, as long as they are non-exported dependencies.
All in all, JSR-277 seems like a huge bunch of features and functionality, that has the possibility of a major impact on the platform as we know it.
The JSR-277 seems to be scheduled for Dolphin and I hope it will make it into that. But I also hope for early adoption of its ideas by the community. The success of such a feature depends upon framework and library authors to embrace it. Just look at what maven has done for a common repository to locate dependencies from and version information in the names of jar files. There was a long time with maven1, where far from all projects embraced its use.
So, what do you think, will JSR-277 take us out of the Dependency-Hell? I sure do hope so!