やりたいこと
あるプロジェクトが依存しているJarファイルは次のような構成をしていると仮定します。
com ─ sample ┰ hoge
└ fuga
hogeパッケージとfugaパッケージの配下にはいくつかクラスがあります。今回はクラスについては関係ないので省略します。
いま、com.sampleという入力に対して配下にあるパッケージ名を全て取得するような処理を作成したいです。
つまり、例で言うならばcom.sample.hogeとcom.sample.fugaをList<String>
で返却するメソッドcollectPackageNameFromJar(String rootPackage)
というメソッドを実装したい場面がありました。
サンプルプログラム
public static List<String> collectPackageNameFromJar(String rootPath) {
List<String> packages = new ArrayList<>();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// 受け取ったルートパッケージ名の相対パスを取得
URL root = classLoader.getResource(rootPath.replace('.', '/'));
try (JarFile jarFile = ((JarURLConnection) root.openConnection()).getJarFile()) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".class")) {
String className = entry.getName().replace("/", ".").replace(".class", "");
if (className.startsWith(rootPath + ".")) {
// パッケージ名のみ取得する
String packageName = className.substring(0, className.lastIndexOf('.'));
if (!packages.contains(packageName)) {
packages.add(packageName);
}
}
}
}
} catch (IOException e) {
// TODO 適切な例外処理を入れる
e.printStackTrace();
}
return packages;
}
注意点
Jarファイル内から取得することを前提としているので、単純に自プロジェクト内のパッケージ取得には使えません。
自プロジェクト内のパッケージ名から配下のパッケージ名を取得する場合はFileを使えば実装できます。