Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List all subpackages of a package

Tags:

java

spring

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? enter image description here

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?

like image 451
Xin Avatar asked Apr 09 '13 04:04

Xin


1 Answers

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")
like image 138
Dmitry Erokhin Avatar answered Oct 24 '22 00:10

Dmitry Erokhin