BLOGTIMES
2012/01/19

Javaで特定のパッケージに含まれるクラスの一覧を取得する

  java 
このエントリーをはてなブックマークに追加

Java であるパッケージに含まれるクラスの一覧を取得したかったのですが、リフレクションのAPIに一撃でやれるようなものはないみたいなので実現方法をいろいろ調べてみました。
とりあえず自分で作ったクラスだけに限定するのであれば下記で紹介されているものが使えそうです。

Get all classes within a package [java] [introspection] [class] [package]

The code below gets all classes within a given package. Notice that it should only work for classes found locally, getting really ALL classes is impossible

以下、作業メモ。

サンプルコード

基本的には 「Get all classes within a package [java] [introspection] [class] [package]」 で紹介されているコードを起動出来るようにして、先日の Jersey を動かしたときのプロジェクトに適用してみたというものです。

ClassListExample.java

package jaxrsexample; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; public class ClassListExample { @SuppressWarnings("rawtypes") public static void main(String[] args) throws Exception { for (Class klass : getClasses("jaxrsexample")) { System.out.println(klass.getName()); } } /** * Scans all classes accessible from the context class loader which belong * to the given package and subpackages. * * @param packageName * The base package * @return The classes * @throws ClassNotFoundException * @throws IOException */ @SuppressWarnings("rawtypes") private static List<Class> getClasses(String packageName) throws ClassNotFoundException, IOException { ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); assert classLoader != null; String path = packageName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(path); List<File> dirs = new ArrayList<File>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); String fileName = resource.getFile(); String fileNameDecoded = URLDecoder.decode(fileName, "UTF-8"); dirs.add(new File(fileNameDecoded)); } ArrayList<Class> classes = new ArrayList<Class>(); for (File directory : dirs) { classes.addAll(findClasses(directory, packageName)); } return classes; } /** * Recursive method used to find all classes in a given directory and * subdirs. * * @param directory * The base directory * @param packageName * The package name for classes found inside the base directory * @return The classes * @throws ClassNotFoundException */ @SuppressWarnings("rawtypes") private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException { List<Class> classes = new ArrayList<Class>(); if (!directory.exists()) { return classes; } File[] files = directory.listFiles(); for (File file : files) { String fileName = file.getName(); if (file.isDirectory()) { assert !fileName.contains("."); classes.addAll(findClasses(file, packageName + "." + fileName)); } else if (fileName.endsWith(".class") && !fileName.contains("$")) { Class _class; try { _class = Class.forName(packageName + '.' + fileName.substring(0, fileName.length() - 6)); } catch (ExceptionInInitializerError e) { // happen, for example, in classes, which depend on // Spring to inject some beans, and which fail, // if dependency is not fulfilled _class = Class.forName( packageName + '.' + fileName.substring(0, fileName.length() - 6), false, Thread.currentThread().getContextClassLoader()); } classes.add(_class); } } return classes; } }

実行結果はこんな感じで、作成したクラスが列挙されることが確認できました。

jaxrsexample.ClassListExample jaxrsexample.Hello jaxrsexample.Hello2 jaxrsexample.Hello3 jaxrsexample.Item jaxrsexample.Items

今回僕がやりたいことはこれで十分なので、これでいきたいと思います。


    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/4717
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン