Monday, April 21, 2014

A list of solutions to solve the jar hell

Jar Hell is the situation when you have the different incompatible versions of library existed in your classpath simultaneously. For example, you have  a project that depends on library A version 2.0, and you also need a third party library B which depends on library A version 1.0, then the library version 1.0 and version 2.0 will all be included in your classpath, it will cause some problems because machine doesn't know which version to choose in the right place.

I just encountered this problem in my recent project, so I did a lot of research of it. However, in theory, there's no best way to resolve it. So I list all the possible solutions here:

1. Avoid

First of all, you should consider this problem before you proceed. Find all the dependencies that your library will use, and make sure all library versions are compatible. It will save your a lot of troubles!

2. Find a transition version that works for both sides

If it already happened, then you should consider finding a transition version. Library changes gradually, so you may be luck to find a right version.

3. Use Jarjar

If your project won't involve any shared interface between the incompatible versions, then you should definitely try Jarjar, a jar wrap tool that can rename the embedded class files. It works like a charm, will do a lot of work with your imagination. There's a blog talking about it.
However, there are one limitation you should know:
If the incompatible versions of library have different interfaces, and these interfaces will be used in your project, then you are no lucky because even they have the some interface name, they are in different packages(jarjar changed the package name), so they are definitely different interfaces, you can't assign instances directly. 
But there is also a solution to this case, which is to write adapter classes to wrap one interface to the other, it works in some situations.

4. Modify library source code

If you have access to the library source code, you could also change the incompatible code by yourself and wrap it as a customized jar to fulfill your need. It works well when the difference between versions is not that much.

5. Access Rule & Maven solution

I didn't dig into it too much, but it seems workable to some situation. The Access Rule (see this article) can forbid some classes from using. The Maven also have similar access rules.

No comments:

Post a Comment