承認これくしょん

my black histories

クラスが含まれるjarを検索するスクリプト

既存のJavaプロジェクトをビルドしようとしたらjarの参照が切れていた。
しかも必要なクラスがどのjarに入ってるかわからず、大量のjarの山から探さなければ…という辛い状況で便利かもしれません。
JDK付属のjrunscriptを使います。

使い方

jrunscript classFinder.js (検索対象クラス) (検索対象ディレクトリ)…

検索対象クラスは完全限定名でもそうじゃなくてもヒットするはず。
検索対象ディレクトリは複数指定可。それぞれのディレクトリとそのサブディレクトリ内のjarについて該当のクラスが含まれるか調べます。

ソース (classFinder.js)

var File = java.io.File;
var JarFile = java.util.jar.JarFile;
var JarEntry = java.util.jar.JarEntry;
var Collections = java.util.Collections;

var matcher;

if (arguments.length != 0) {
  matcher = new RegExp('^(.+/)*' + arguments[0].replace(/\./g,'/') + '\.class$');
  findJars(arguments.slice(1));
}

function findJars(dirPaths) {
  while (dirPaths.length != 0) {
    var dir = new File(dirPaths.pop());
    var items = dir.listFiles();
    for each (var item in items) {
      if (item.isFile() && item.getName().endsWith('.jar')) {
        findClass(item);
      } else if (item.isDirectory()) {
        dirPaths.push(item);
      }
    }
  }
}

function findClass(file) {
  var jarFile = new JarFile(file);
  var entries = Collections.list(jarFile.entries());
  for each (var entry in entries) {
    if (matcher.test(entry)) print(file + ': '+ entry);
  }
}

JarFile.entries()の戻り値がEnumerationでどうすんのこれ…って思ったけどArrayListに変換できてよかった。Collections便利。
なんかfor-each文がAS3(というか幻のES4?)っぽいですね。