I am looking for a way to list all the subpackages of an arbitrary package in Java.
Something like this:
Package basePackage = getPackage("com.mypackage");
for(Package subPackage : basepackage.getSubPackages()){
System.out.println(subPackage.getName());
}
Is there a way to do it? Thanks in advance.
How does IDE(let's say Netbeans) do it?
UPDATE:
I am trying to find all the mappers package for MyBatis. In my project, all the mappers packages has to name "*.mappers". For example: "a.b.mappers" or "a.b.c.mappers". The thing is I only know the base package, and not sure how many mappers packages under it.
UPDATE: Here is my code trying to use reflection library to do it:
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;
}
Not sure why this does not work. No class is found here....
UPDATE
Here is my code to do it. Kind of slow, but the performance is not that big concern in my case. I have never used Spring before, so if there are better ways to do it, let me know. Thanks.
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));
}
Most of the code is copied from How do I read all classes from a Java package in the classpath?
I suppose the easiest way to get packages is to get all packages of your class loader with
Package.getPackages()
and filter it with your package name with
packageName.startsWith("com.yourcompany.yourpackage")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With