Browse DevX
Sign up for e-mail newsletters from DevX


Put an End to Jar File and Class Name Conflicts : Page 2

Uncover hard-to-find class name conflicts and jar file version discrepancies and redundancies with a simple audit utility.

Undetected Redundancy in Jar Files
Before addressing how to implement the auditor, let's first clarify some classpath issues that can negatively impact your code. The classpath is an environmental variable that tells the Java Virtual Machine (JVM) where to find the resources (.class files, .jar files, and certain properties files such as jndi.properties) that it needs to load. Unfortunately, the classpath variable's settings can't warn you when you reference two jar files with the same name that might contain different versions of the same classes. Nor can it tell you whether two jars with different names on your classpath contain identically named classes. Even if the jar files are in different packages this opportunity for redundancy can be a problem, because the JVM will load only one version of the class and you won't know which one has loaded until you encounter a problem and start to debug.

Unfortunately, Java has no mechanism for identifying this problem or reliably tracking versioning in libraries. You could modify the source code to monitor the classloading process so you can get some idea of what is loading, but this solution is possible only if you control the source code. Alternatively, the Java Security Manager mechanism can help avoid some naming clashes by limiting the code bases that can execute in any given application. Unfortunately, many applications are delivered with wide open file permissions and no security manager set.

Dangerous Misconceptions About Classloading
When the JVM boots up at runtime, the bootstrap classloader (also sometimes called the primordial classloader) loads Java's core API (rt.jar). It then calls the "extension" classloader, which loads all the classes that are in the /jre/lib/ext directory of your Java installation. After the extensions directory loads, the system classloader loads any classes on your system's classpath, as specified in your individual personal profile or the OS environmental classpath variable for the system.

As the developer, you control the only other two ways in which additional classes can be loaded. One means of control is using the command line '– classpath' argument to specify additional jar files or directories that the program should consult for class resources. The other way is explicitly instantiating a classloader in your application and specifying the URL to the resources you wish to load. (I mention this last option only for completeness. It is outside the scope of this article. Consult the Related Resources section of this article for further reading.)

Java's classloading mechanism works on a delegation model. In practice, this means that as each classloader prepares to load a class it checks whether a class of that particular name was loaded by any of its parent classloaders. If the class was loaded by a parent classloader then the currently active classloader uses the already loaded class. Otherwise, it loads the requested class for the first time. Developers with an incomplete understanding of this mechanism erroneously conclude that putting classes higher in the classloader delegation hierarchy is a sound practice, because they can be sure that a particular class will always load in a particular order.

This practice isn't good at all, however. Taken to its logical conclusion, it suggests that you should put all classes in the /ext directory, but this only moves the location of the version problem. Moreover, by throwing everything into the /ext directory you undermine the granularity of the Java security mechanism, because the /ext directory typically has "all permissions" set in the java.policy file.

Thanks for your registration, follow us on our social networks to keep up-to-date