One of the great things about Java tool chain is that it accepts the Unix principle of “small sharp tools”. So, instead of some crazy proprietary binary format, java libraries are either .class files in a directory tree that mirrors their package hierarchy or they’re a .zip file, again with the paths of the .class files it contains mirroring their package hierarchy (that’s all a .jar file is).

This means that you don’t need to use specialized tools to do some simple browsing. For example, I’ve recently needed to construct an SDK to work with a third party web-based application that we’re using at my day job. The vendor doesn’t have a productized SDK that I can use, but I do have a working server, so in theory I have all the .jar files that I need *somewhere*. All I needed to do is figure out where.

Since a .jar file is just a Zipped archive of class files, if I can get the list of each .class file in all the .jars on the system, I should be able to figure out which one holds the class I needed, and just copy that to my development machine.

The command to get the list of .class files in a .jar file is this:

jar.exe -tvf jar file name

To only list those files that match the name of your class, do this.  Note that you can use the entire path, like com.mycompanyname.MyClassName.  Jar outputs ‘/’s instead ‘.’s to separate package segments, since as far as jar is concerned, these are file paths, not java package names, but since the ‘.’ is a findstr pattern that means ‘match any character’, it works just fine):

jar.exe -tvf jar file name | findstr class name

To recursively perform a command on all jar files in a directory tree, you use the FOR command, like this:

for /r tree root %f in (*.jar) do my command to %f

Combined, they look like this:

for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name

Unfortunately, this just outputs the names of the class files that match the class name argument. What we really want is the names of the .jar files. It’s in %f, so all we need to do is ECHO %f. But, we only want to do that if FINDSTR found a match. For that, we need the && operator – cmd1 && cmd2 executes cmd1, and if cmd1 sets ERRORLEVEL to 0, executes cmd2. Since FINDSTR sets ERRORLEVEL to 0 on match and 1 on no match, this will work perfectly.

Here’s the final result:

for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name && echo %f

Or, if we just want to see the .jar names, and not the names of the .class files in that .jar that matched:

for /r tree root %f in (*.jar) do jar.exe -tvf %f | findstr class name > NUL && echo %f

Leave a Reply