ClassGraph 5 is an interim release, only intended to support the use of ClassGraph on JDK 17 to 24. Upgrade to ClassGraph 6 as soon as you can run your code on JDK 25 or newer. ClassGraph 6 is the new mainline release. It has the same API and behavior as ClassGraph 5, so the move is a version bump; ClassGraph 6 is fully modernized and removes a lot of legacy code. ClassGraph 5 will be kept in sync with ClassGraph 6 for the near future, on the v5 branch.
ClassGraph 5 is a rewrite of the ClassGraph API, and is not source- or binary-compatible with 4.x. The porting guide walks through the port step by step, and a coding agent can follow it for you. (The guide is written for ClassGraph 6, and applies unchanged to ClassGraph 5.)
What is new
- ClassGraph is split into five reusable libraries, so a project depends only on the part it uses:
classgraph-base-- shared internals, and the verbose log.classgraph-vfs-- a read-only virtual filesystem over directories, jarfiles and modules, and the fastest, most flexible, most powerful and most parallelizable virtual filesystem for the JVM ecosystem. It opens a directory, jarfile or module however it is named, reads jarfiles nested to any depth in place without extracting them, and returns content as a stream, channel,ByteBuffer, byte array, string orjava.nio.file.Path. Lookups and reads take no locks: looking up every entry of a 26,970-entry jarfile is 6× faster thanjava.util.zip.ZipFileon one thread and 141× faster on 32 threads. See the benchmarks. The scanner itself now reads through it.classgraph-classpath-- finds the classpath and module path of a running JVM, in classloader order, including the classpath of Spring Boot, Tomcat, JBoss, WebLogic, WebSphere, OSGi, Quarkus and other container classloaders. You can now register your ownClassLoaderHandlerfor a classloader ClassGraph does not know.classgraph-- scanning, and the class graph API. Depending on it brings in the three above.classgraph-viz-- GraphViz.dotfile generation.
- Nothing is scanned until you say what to scan: a scan enables the classpath, the module path, or specific classloaders, module layers or classpath entries.
- Consistent naming:
getAll...for a transitive closure andgetDirect...for the direct answer, so the 4.x mistake of using a transitive result as a direct one cannot happen silently. One glob syntax everywhere. - ClassGraph no longer loads classes, so it no longer runs static initializers as a side effect of a query or keeps classloaders alive after a scan. Load classes yourself with
Class.forName(). - A stricter, more modern API: nullability declared throughout with JSpecify; every returned collection is unmodifiable; lists instead of arrays and getters instead of public fields; fluent setters everywhere; callbacks are
PredicateandConsumer. - JDK 17 is the minimum, so the reflection that 4.x used to reach newer JDK features is gone. The JSON serializer has been removed.
A large number of bugs were found and fixed during the transition from ClassGraph 4 to ClassGraph 5 and 6. The most important fixes were backported to ClassGraph 4.
Getting it
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>5.0.0</version>
</dependency>