How to find all the classes of a package in Java
Tags: java, tutorial, classpath, scanner
Published: 2020-12-07 08:35:06

To find all classes of a package in Java we need to use the [**ClassHunter**](https://www.burningwagve.org/in-depth-look-to-and-configuration-guide/) of [**Burningwave Core**](https://burningwave.github.io/core/) library. The ClassHunter is a classpath scan engine that queries iterated classes and returns only the classes that match a chosen criteria, moreover the searches are executed in a multithread context and recursively through folder and supported compressed files (zip, jar, jmod, war and ear) even in nested compressed files. **To use the ClassHunter you should simply add the following to your projects dependencies:**

{% gist https://gist.github.com/Roberto-Gentili/536ee2d3f775030d46d82a008da10dbe.js %}

To perform a scan it is necessary to create a configuration object of type **SearchConfig** to which must be (optionally) passed the paths to be scanned and the query criteria represented by the **ClassCriteria**. If no path will be passed to SearchConfig, the scan will be executed on the paths indicated by the ‘**paths.hunters.default-search-config.paths**’ property of the [burningwave.properties](https://www.burningwave.org/overview-and-configuration/#configuration-2).

**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:

```java
try (SearchResult result = classHunter.findBy(
    //Highly optimized scanning by filtering resources before loading from ClassLoader
    SearchConfig.forResources(
        "org/springframework"
    )
)) {
    return result.getClasses();
}
```

The **findBy** method loads all classes in the paths of the SearchConfig received as input and then execute the queries of the ClassCriteria. The findBy method also caches data so after the first search it is possible to take advantage of faster searches. In addition to the loadCache method, loading data into the cache can also take place via the findBy method if the latter receives a SearchConfig without ClassCriteria as input.

## **Finding all classes that have package name that matches a regex**
```java
ComponentSupplier componentSupplier = ComponentContainer.getInstance();
ClassHunter classHunter = componentSupplier.getClassHunter();

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

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

## **Finding all annotated classes of a package without considering the classes hierarchy**
```java
try (
    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**
```java
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**
```java
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().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**
```java
try (
    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();
}
```
In this article we learned how to find all classes within a package and the complete code of the example above is available [here](https://www.burningwave.org/how-to-find-all-classes-in-a-package/).