Showing posts with label jars. Show all posts
Showing posts with label jars. Show all posts

Sunday, July 8, 2007

Closures in Action: searching jars

A recent blog post talks about the problem of searching jars for class names. I have done something similar in Java, and ported the solution to Groovy.

The code is listed below. Some tidbits:

  • My uncommented Java program was 87 lines. The commented Groovy program is under 50.
  • The program is not fast but is straight-forward. It recursively searches a directory for jars, and searches each jar for a given string (e.g. "org/apache/log4j/Logger").
  • It uses 2 closures. This is a modest example of the power of generic algorithms (e.g. eachFile()) and closures.
  • If you aren't familiar with closures, Groovy is a fantastic way to "test drive" them before deciding on your stance about including them in Java.
// Usage:
// groovy Which [searchDir] [target]
//
// e.g. groovy Which c:\tomcat org/apache/log4j/Logger

import java.io.File;
import java.util.jar.JarFile;

// Closure: if jarEntry's name matches target, print fileName
// NOTE: fileName value comes from enclosing scope
myEntryChecker = {
jarEntry ->
int index = jarEntry.getName().indexOf(target);

if( index != -1 ) {
println "found match in " + fileName;
}
}

// Closure: if file is a jar, apply myEntryChecker
myFileChecker = {
file ->
if( file.isFile() && file.canRead() ) {
fileName = file.getName();

if( fileName.indexOf(".jar") != -1 ) {
JarFile jarFile = new JarFile(file);
jarFile.entries().each(myEntryChecker);
}
}
}

////////////////////////////////////////////////
// static void main(String args[])
//
// todo: sanity check arguments
def fileName
searchDir = args[0]
target = args[1]
println "\nsearching: " + searchDir
println "target: " + target + "\n"

new File(searchDir).eachFileRecurse(myFileChecker)

println "\ndone. "