|
Conquer Class Loader Confusion
The ClassLoader solution is a one-time cost that provides a way out of class versioning conflicts
by Daniel F. Savarese
February 24, 2005
Of late, I've been hearing many complaints from colleagues and acquaintances about running into software versioning conflicts with J2EE application servers. The basic problem has existed for quite some time, but it would seem that there are now enough Java libraries shared between applications and application servers to exacerbate the problem. Versioning conflicts occur when an application server uses version A of a Java package, an application to be hosted by the server uses version B of the same package, and versions A and B are incompatible. When the application tries to use the package, the classes from version A are loaded instead of the ones from version B. If the classes behave differently, problems ensue.
This situation is common, in part, because so many application servers rely on open source software to some extent. The release cycle of commercial software is typically not as fast as that of open source software. Therefore, newly released application servers often do not include the latest versions of libraries. In addition, enterprise software upgrade cycles lag behind vendor release cycles, sometimes skipping releases for the sake of maintaining stability. Consequently, developers using the latest and greatest Java libraries run headlong into J2EE servers that incorporate older versions of the libraries.
The problem also emerges going the other direction. An enterprise application that has been around for several years may encounter an incompatibility when the application server is upgraded. If the program depends on an older version of a library packaged with the application server, the new library may cause run-time exceptions such as NoSuchMethodException when the program tries to access an API element that no longer exists.
Much of the time, developers don't notice that a different version of a library—here I consider a library to be a collection of Java packages—is being used because they aren't using parts of the API that have changed or aren't triggering bugs that may have been fixed in a later version. When the problem arises, developers have to figure out a way around it. Replacing the application server libraries can break the application server or other applications it hosts. If the developer doesn't have administrative control over the application server, that solution is not even possible.
Share and Share Alike
The crux of the problem is that most J2EE vendors have designed their products with a class-loading hierarchy that ultimately delegates to the application server's class loader. Even though separate class loaders are designated for each Web application—keeping Web applications from interfering with each other—the libraries used by the server itself are shared by all Web applications. I would speculate that there must be some products that don't have this problem, but I've heard reports of it surfacing on most of the major closed and open source products.
One approach programmers use to work around versioning conflicts is to change the names of the packages in the library source code to unique names used only by their code, recompile the library, and update all import statements and other references to package names in their source code. This solution works only if you have access to the library source code, which is not always the case. Although source code modification and recompilation is a reliable, short-term solution, it is time consuming in the long run. Writing shell scripts or using an IDE plug-in can automate package renaming.
Back to top
|