Я ищу способ перечислить все подпакеты произвольного пакета в Java.
Что-то вроде этого:
Package basePackage = getPackage("com.mypackage");
for(Package subPackage : basepackage.getSubPackages()){
System.out.println(subPackage.getName());
}
Есть ли способ сделать это? Спасибо заранее.
Как делает IDE (скажем, Netbeans)?
UPDATE:
Я пытаюсь найти все пакеты mappers для MyBatis. В моем проекте все пакеты mappers должны называть "*.mappers". Например: "a.b.mappers" или "a.b.c.mappers". Дело в том, что я знаю только базовый пакет и не уверен, сколько пакетов пакетов под ним.
UPDATE: Вот мой код, пытающийся использовать библиотеку отражений для этого:
private Set<String> getPackagesNames() {
Reflections reflections = new Reflections("com.mypackage");
Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class);
Set<String> packageNames = new HashSet<>();
for( Iterator<Class<? extends Object>> it = allClasses.iterator(); it.hasNext(); ) {
Class<? extends Object> subClass= it.next();
packageNames.add(subClass.getPackage().getName());
}
return packageNames;
}
Не знаю, почему это не работает. Здесь нет класса.
UPDATE
Вот мой код, чтобы сделать это. Вид медленный, но производительность не так уж важна в моем случае. Я никогда не использовал Spring раньше, поэтому, если есть лучшие способы сделать это, дайте мне знать. Спасибо.
private static Set<String> getPackages(String basePackage) throws IOException, ClassNotFoundException {
Set<String> packagesNames = new HashSet<>();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + "**/*.class";
Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
for( Resource resource : resources ) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
Class aClass = Class.forName(metadataReader.getClassMetadata().getClassName());
String packageName = aClass.getPackage().getName();
packagesNames.add(packageName);
}
}
return packagesNames;
}
private static String resolveBasePackage(String basePackage) {
return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage));
}
Большая часть кода скопирована из Как читать все классы из пакета Java в пути к классам?