- One case is when a developer or deployer of a Java application has accidentally made two different versions of a library available to the system. This is not considered an error by the system. Rather, the system will load classes from one or the other library. A developer who thinks he has replaced a library with a new version, but who has instead simply added the new library to the list of available libraries, may be surprised to see the application still behaving as though the old library is in use, which it may well be.
- Another version of the problem arises when two libraries (or a library and the application) require different versions of the same third library. If both versions of the third library use the same class names, there is no way to load both versions of the third library with the same classloader.
- The most complex JAR hell problems arise in circumstances that take advantage of the full complexity of the classloading system. A Java program is not required to use only a single “flat” classloader, but instead may be composed of several (or, in fact, an indefinite number of) nested, cooperating classloaders. The interactions between classloaders is too complex to be fully described here. It is sufficient to say that classes loaded by different classloaders may interact in ways which may not be fully comprehended by the developer, leading to inexplicable errors or bugs.
The OSGi Alliance specified (starting as JSR 8 in 1998) a modularity framework that solved JAR hell for current and future VM’s both in ME, SE, and EE that is widely adopted. Using metadata in the JAR manifest, JAR files (called bundles) are wired on a per-package bases. Bundles can export packages, import packages and keep packages private, providing the basic constructs of modularity and versioned dependency management