How to find all classes in a package in Java

In order to find all classes in a package in Java we need to use the ClassHunter. So let’s start by adding the following dependency to our pom.xml:

<dependency>
    <groupId>org.burningwave</groupId>
    <artifactId>core</artifactId>
    <version>12.64.3</version>
</dependency>

… And to use Burningwave Core as a Java module, add the following to your module-info.java:

requires org.burningwave.core;

Then next steps are the following:

  • retrieving the ClassHunter through the ComponentContainer
  • defining a regular expression that we must pass to the ClassCriteria object that will be injected into the SearchConfig object
  • calling the findBy method that loads in the cache all loadable classes of the indicated paths, then applies the criteria filter and then returns the SearchResult object which contains the classes that match the criteria

The fastest and most optimized way to find all the classes of a package is by iterating the resources accessible through ClassLoader thus avoiding that ClassLoader loads the classes that are outside the scanned paths:

import java.util.Collection;

import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassHunter;
import org.burningwave.core.classes.ClassHunter.SearchResult;
import org.burningwave.core.classes.SearchConfig;
    
public class ClassForPackageFinder {
    
    public Collection<Class<?>> find() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        ClassHunter classHunter = componentSupplier.getClassHunter();
        
        try (SearchResult result = classHunter.findBy(
        	//Highly optimized scanning by filtering resources before loading from ClassLoader
    	    SearchConfig.forResources(
    	        "org/springframework"
    	    )
    	)) {
    	    return result.getClasses();
    	}
    }
    
}

Another fast way to get all the classes in a package is to add a filter that will be applied when scanning the files and before loading the classes:

import java.util.Collection;

import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassHunter;
import org.burningwave.core.classes.JavaClass;
import org.burningwave.core.classes.SearchConfig;
import org.burningwave.core.io.FileSystemItem;
    
public class Finder {
    
   public Collection<Class<?>> find() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        ClassHunter classHunter = componentSupplier.getClassHunter();
        
        SearchConfig searchConfig = SearchConfig.create().setFileFilter(
            //Highly optimized scanning by filtering resources before loading from ClassLoader            
            FileSystemItem.Criteria.forAllFileThat( fileSystemItem -> {
                JavaClass javaClass = fileSystemItem.toJavaClass();
                if (javaClass == null) {
                    return false;
                }
                String packageName = javaClass.getPackageName();                       
                return packageName != null && packageName.contains("springframework");
            })
        );

        try(ClassHunter.SearchResult searchResult = classHunter.findBy(searchConfig)) {
            return searchResult.getClasses();
        }
    }
    
}

In the forPaths method you can add all absolute paths you want: both folders, zip, jar, ear, war and jmod files will be recursively scanned. For example you can add: “C:\Users\user\.m2”, or a path of an ear file that contains nested war with nested jar files. With the line of code in the example above the search will be executed on runtime class paths and, on java 9 and later, also on .jmod files contained in jmods folder of the Java home. You can also instantiate the SearchConfig object without calling the forPaths method: in this case the scan will be executed through the default configured paths (see “The ClassHunter: in depth look to and configuration guide“).


Finding all classes that have package name that matches a regex

In the following example we are going to find all classes that have package name that matches a regex and in particular we look for all classes whose package name contains “springframework” string using the ClassCriteria:

import java.util.Collection;

import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassCriteria;
import org.burningwave.core.classes.ClassHunter;
import org.burningwave.core.classes.SearchConfig;
    
public class Finder {
    
    public Collection<Class<?>> find() {
    	ComponentSupplier componentSupplier = ComponentContainer.getInstance();
    	ClassHunter classHunter = componentSupplier.getClassHunter();

    	SearchConfig searchConfig = SearchConfig.byCriteria(
    	    ClassCriteria.create().allThoseThatMatch((cls) -> {
    	    	String packageName = cls.getPackage().getName();
    	        return packageName != null && packageName.matches(".*springframework.*");
    	    })
    	);

    	try (ClassHunter.SearchResult searchResult = classHunter.findBy(searchConfig)) {
    	    return searchResult.getClasses();
    	}
    }
    
}

Finding all annotated classes of a package without considering the classes hierarchy

import java.util.Collection;

import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassCriteria;
import org.burningwave.core.classes.ClassHunter;
import org.burningwave.core.classes.ConstructorCriteria;
import org.burningwave.core.classes.FieldCriteria;
import org.burningwave.core.classes.MethodCriteria;
import org.burningwave.core.classes.SearchConfig;
    
public class Finder {
    
    
    public Collection<Class<?>> find() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        ClassHunter classHunter = componentSupplier.getClassHunter();
        
        try (ClassHunter.SearchResult result = classHunter.findBy(
                //Highly optimized scanning by filtering resources before loading from ClassLoader
                SearchConfig.forResources(
                    "org/springframework"
                ).by(
                    ClassCriteria.create().allThoseThatMatch((cls) -> {
                        return cls.getAnnotations() != null && cls.getAnnotations().length > 0;
                    }).or().byMembers(
                        MethodCriteria.withoutConsideringParentClasses().allThoseThatMatch((method) -> {
                            return method.getAnnotations() != null && method.getAnnotations().length > 0;
                        })
                    ).or().byMembers(
                        FieldCriteria.withoutConsideringParentClasses().allThoseThatMatch((field) -> {
                            return field.getAnnotations() != null && field.getAnnotations().length > 0;
                        })
                    ).or().byMembers(
                        ConstructorCriteria.withoutConsideringParentClasses().allThoseThatMatch((ctor) -> {
                            return ctor.getAnnotations() != null && ctor.getAnnotations().length > 0;
                        })
                    )
                )
            )
        ) {
            return result.getClasses();
        }
    } 
}

Finding all annotated classes of a package by considering the classes hierarchy

import java.util.Collection;

import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassCriteria;
import org.burningwave.core.classes.ClassHunter;
import org.burningwave.core.classes.ClassHunter.SearchResult;
import org.burningwave.core.classes.ConstructorCriteria;
import org.burningwave.core.classes.FieldCriteria;
import org.burningwave.core.classes.MethodCriteria;
import org.burningwave.core.classes.SearchConfig;
    
public class ClassForPackageAndAnnotationFinder {
    
    public Collection<Class<?>> find() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        ClassHunter classHunter = componentSupplier.getClassHunter();
        
        try (
                SearchResult result = classHunter.findBy(
                //Highly optimized scanning by filtering resources before loading from ClassLoader
                SearchConfig.forResources(
                    "org/springframework"
                ).by(
                    ClassCriteria.create().allThoseThatHaveAMatchInHierarchy((cls) -> {
                        return cls.getAnnotations() != null && cls.getAnnotations().length > 0;
                    }).or().byMembers(
                        MethodCriteria.forEntireClassHierarchy().allThoseThatMatch((method) -> {
                            return method.getAnnotations() != null && method.getAnnotations().length > 0;
                        })
                    ).or().byMembers(
                        FieldCriteria.forEntireClassHierarchy().allThoseThatMatch((field) -> {
                            return field.getAnnotations() != null && field.getAnnotations().length > 0;
                        })
                    ).or().byMembers(
                        ConstructorCriteria.forEntireClassHierarchy().allThoseThatMatch((ctor) -> {
                            return ctor.getAnnotations() != null && ctor.getAnnotations().length > 0;
                        })
                    )
                )
            )
        ) {
            return result.getClasses();
        }
    }
    
}

Finding all classes of a package that have a particular annotation on at least one Field without considering the classes hierarchy

import java.util.Collection;

import javax.validation.constraints.NotNull;

import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassCriteria;
import org.burningwave.core.classes.ClassHunter;
import org.burningwave.core.classes.FieldCriteria;
import org.burningwave.core.classes.SearchConfig;
    
public class Finder {
    
    public Collection<Class<?>> find() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        ClassHunter classHunter = componentSupplier.getClassHunter();
        
        try (
        	ClassHunter.SearchResult result = classHunter.findBy(
                //Highly optimized scanning by filtering resources before loading from ClassLoader
                SearchConfig.forResources(
                    "org/springframework"
                ).by(
                    ClassCriteria.create().byMembers(
                        FieldCriteria.withoutConsideringParentClasses().allThoseThatMatch((field) -> {
                            return field.getAnnotation(NotNull.class) != null;
                        })
                    )
                )
            )
        ) {
            return result.getClasses();
        }
    }
    
}

Finding all classes of a package that have a particular annotation on at least one Field by considering the classes hierarchy

import java.util.Collection;

import javax.validation.constraints.NotNull;

import org.burningwave.core.assembler.ComponentContainer;
import org.burningwave.core.assembler.ComponentSupplier;
import org.burningwave.core.classes.ClassCriteria;
import org.burningwave.core.classes.ClassHunter;
import org.burningwave.core.classes.FieldCriteria;
import org.burningwave.core.classes.SearchConfig;
    
public class Finder {
    
    public Collection<Class<?>> find() {
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
        ClassHunter classHunter = componentSupplier.getClassHunter();
        
        try (
        		ClassHunter.SearchResult result = classHunter.findBy(
                //Highly optimized scanning by filtering resources before loading from ClassLoader
                SearchConfig.forResources(
                    "org/springframework"
                ).by(
                    ClassCriteria.create().byMembers(
                        FieldCriteria.forEntireClassHierarchy().allThoseThatMatch((field) -> {
                            return field.getAnnotation(NotNull.class) != null;
                        })
                    )
                )
            )
        ) {
            return result.getClasses();
        }
    }
    
}

Flexible

It’s possible to search classes by every criteria that your imagination can make by using lambda expressions

Optimized

Scan engine is highly optimized using direct allocated ByteBuffers to avoid heap saturation

Open

Burningwave core is an advanced free and open source Java library