Monday, February 7, 2011

Finding Multiple Class Definitions with Jarminator

One of the advantages of being a Java developer is the wide assortment of tools, libraries, and frameworks available to make Java development easier. Several months ago, a colleague introduced my to Jarminator, a little open source produce that is surprisingly (pleasantly) helpful in Java development. It has also been referenced on DZone. In this post, I look at Jarminator and how it can be helpful to the Java developer.

The main project page for Jarminator v0.15 is filled with screen snapshots demonstrating Jarminator in action. A Java developer who is aware of this product's existence and accesses this main page should have no trouble using Jarminator. The usage can also be found by running one of the batch files (jarminator_debug) with the -? option as shown in the next screen snapshot.


The single ZIP file can be downloaded at http://sourceforge.net/projects/jarminator/files/ and version 0.15 is a tad over 50kb in size. Once downloaded, its "installation" is simple (unzip it into whatever location you like). From that point, it can be run in Windows with the provided batch files. One simply needs to change directory to the directory into which the contents of the jarminator.zip were extracted and type "jarminator" on the command line.

Most Java developers can recount numerous stories of situations where their applications ran into exceptions and other misbehavior such as ClassNotFoundException and NoClassDefFoundError. These are sometimes trivial to fix. For example, a ClassNotFoundException is easy to address if it is determined that the particular class is not on the classpath. Errors and exceptions and other misbehavior can also occur when more than one definition of the same class are on the classpath. I remember many traumatic episodes dealing with different versions of Xerces supplied by different frameworks several years ago. All of these issues are more easily dealt with when Jarminator is applied.

Jarminator aids the Java developer by providing a simple, graphically-based view of classes associated with specified JARs. It makes the developer's job of determining which classes are on the classpath and which are not on the classpath much easier. It makes duplicate classes obvious by listing the duplicates in a gray font.

To demonstrate this, I have loaded Groovy JAR files from both the Groovy distribution installed on my machine and from a Spring Framework distribution installed on my machine into Jarminator as shown in the next screen snapshot.


One way to specify the JARs for Jarminator load is to click on the "Browse" button and to select the appropriate JAR. However, I find it often most useful to simply copy-and-paste my specified classpath (whatever follows -cp or -classpath) into that "Source" field. Once the source JARs are specified (either by using the "Browse" button to select them or by pasting or typing them in), clicking on the "Load" button instructors Jarminator to load metadata about the JARs' contents.

Once the JARs' contents have been loaded into Jarminator, the JARs that have been loaded successfully are listed in the "Jars" tab as shown in the above screen snapshot. This is useful to ensure that the classpath typed in was valid and was for a valid JAR that Jarminator understands. The "Classes" tab is the one that is most helpful. This tab lists all of the classes contained in the JARs specified in the "Source" field. An example of this is shown in the next screen snapshot.


The preceding screen snapshot shows that the various packages of classes found in the loaded JARs are displayed in the "Classes" tab. Clicking on these packages expands them to show the classes that reside within the packages. This is shown in the next screen snapshot.


Thanks to Jarminator, it is easy to identify that many of these classes are duplicate (the ones in gray indicate duplicates). Although it's nice to know there are duplicates, it is far more useful to know where the duplicate definitions are coming from. This can be determined by clicking on the duplicate classes. Once clicked on, Jarminator indicates where each class definition source is. This is shown in the next two screen snapshots which show the duplicate Closure class being defined in the Groovy distribution and in the Spring Framework distribution. With this knowledge, the developer can then remove the inappropriate source definition from the classpath.



The bottom left corner of the Jarminator GUI indicates the source of the class definition that is highlighted. In the case shown in the screen snapshots above, the Spring Framework supplied version is considered the duplicate, though, of course, that decision is really up to the developer based on the context of the application.

I previously mentioned that the "Jars" tab is useful for ensuring that JARs have been appropriately loaded into Jarminator. It also can be used to delve down into the classes provided on a per JAR basis. This is shown in the next screen snapshot.


The Jarminator GUI also features a "Filter" button. As might be expected given its name, this field allows a filter to be specified to only show entries matching the filter. For example, if the developer only cares about .class files and not about other non-class items such as images, the .class filter can be specified and is applied when the "Apply" button is clicked. To see this in action, the next two screen snapshots show Jarminator's display for the case of no filter applied and then having the ".class" filter applied. When no filter is applied, the Grape package contents are shown with the included XML file. When the ".class" filter is applied, the XML file is no longer shown.



Besides demonstrating the utility of Jarminator's filtering capability, the last two screen snapshots also demonstrate the different icons Jarminator uses for different file types within JARs. Java classes (.class files) have a C within a green circle and most of the icons are familiar to Java developers who have used the Eclipse IDE. A summary of the Jarminator icons is shown next.



Jarminator v0.15 also supports a console mode. This is executed with the command jarminator_debug -c followed by the path to be loaded and searched. I have found that if there is more than one JAR file specified (and therefore separated by semicolon) that it is necessary to put the multiple paths within quotes. An example of this is shown in the next two screen snapshots with the first image showing the command used from the console with the beginning of the output and the second image showing the end of the output with a summary line.



Conclusion

As I stated earlier in this post, the main Jarminator page is almost exclusively devoted to coverage of the features of Jarminator. Jarminator is an easy tool to use, but can be a very powerful tool when the Java developer needs to determine classpath conflicts involving insufficient or too many class definitions.

1 comment:

Dustin said...

Tattletale is another tool that can be used to find duplicate class definitions as well as JAR dependencies.