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(); } } }
BackgroundExecutor
ClassFactory
ClassHunter
- In depth look to and configuration guide
- USE CASE: how to retrieve all classes of the classpath
- USE CASE: how to retrieve all classes that implement one or more interfaces
- USE CASE: finding all classes that extend a base class
- USE CASE: how to find all classes in a package
- USE CASE: Finding all classes for module name (Java 9 and later)
- USE CASE: finding all annotated classes
- USE CASE: how to scan classes for specific annotations and collect their values
- USE CASE: how to search for all classes with a constructor that takes a specific type as first parameter and with at least 2 methods that begin for a given string
- USE CASE: how to search for all classes with methods whose name begins for a given string and that takes a specific type as its first parameter
- USE CASE: finding all classes that have at least 2 protected fields
ClassPathHunter
CodeExecutor
FileSystemItem
FunctionalInterfaceFactory
IterableObjectHelper
JavaMemoryCompiler
PropertyAccessor
UnitSourceGenerator