- blogs:
- cles::blog
« Wikipedia が止まってる :: 焼酎居酒屋 すきっぱー »
2012/01/19

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 を使ってログインすることができます。
« Wikipedia が止まってる :: 焼酎居酒屋 すきっぱー »
サイト内検索
検索ワードランキング
へぇが多いエントリ
閲覧数が多いエントリ
1 . Windows 10 で勝手にログアウトされないようにする(3689)
2 . リモートデスクトップで Alt + PrtSc と同じことをするには(3149)
3 . RDP のプロトコルを TCP だけに変更する(2418)
4 . 「日次」は「にちじ」じゃない?(2248)
5 . リモートデスクトップで Ctrl + Alt + Del キーを送信するには(2169)
2 . リモートデスクトップで Alt + PrtSc と同じことをするには(3149)
3 . RDP のプロトコルを TCP だけに変更する(2418)
4 . 「日次」は「にちじ」じゃない?(2248)
5 . リモートデスクトップで Ctrl + Alt + Del キーを送信するには(2169)
cles::blogについて
Referrers