-
-
Notifications
You must be signed in to change notification settings - Fork 298
ScanResult API
See also the ClassGraph API overview.
The .scan()
method produces a ScanResult
, which can be queried for either classes or resources (or both).
🛑 Make sure you call
ScanResult#close()
when you have finished with theScanResult
, or allocate theScanResult
in a try-with-resources block -- seeScanResult
lifecycle below.
try (ScanResult scanResult = new ClassGraph().enableAllInfo().scan()) {
// ...
}
A ScanResult
holds all the ClassInfo
objects and Resource
objects found during a scan:
-
Classes: (N.B. call
.enableClassInfo()
before.scan()
, and call.ignoreClassVisibility()
if you want to scan non-public classes.)-
Querying for a specific named class:
-
.getClassInfo(String className)
returns theClassInfo
object for the named class, or returns null if the named class was not found during the scan.
-
-
Querying for all classes of a given type: Except where indicated, these methods return a
ClassInfoList
ofClassInfo
objects representing the classes.💡 A
ClassInfoList
can be further filtered by calling.filter(ClassInfoFilter)
.-
.getAllClasses()
returns a list of all classes, interfaces and annotations found during the scan. -
.getAllClassesAsMap()
returns aMap<String, ClassInfo>
from class name toClassInfo
for all classes, interfaces and annotations found during the scan. -
.getAllStandardClasses()
returns a list of all standard classes (non-annotation, non-interface classes). -
.getAllAnnotations()
returns a list of all annotations. -
.getAllInterfaces()
returns a list of all non-annotation interfaces. (Annotations are interfaces, and can be implemented.) -
.getAllInterfacesAndAnnotations()
returns a list of all interfaces and annotations (i.e. everything that can be implemented.) -
.getAllEnums()
returns a list of allEnum
classes. -
.getAllRecords()
returns a list of allrecord
types (JDK 14+).
-
-
Querying for all classes related to a named class: These methods look up the named class by calling
getClassInfo(className)
, then if the result is non-null, call the corresponding method in the resultingClassInfo
, returning aClassInfoList
, or the empty list if no results.-
.getSubclasses(String className | Class<?> superclassRef)
returns a list of classes that extend the given superclass. -
.getSuperclasses(String className | Class<?> subclassRef)
returns a list of superclasses of the given class. -
.getInterfaces(String className | Class<?> classRef)
returns a list of interfaces implemented by a given class or by one of its superclasses, if this is a standard class, or the superinterfaces extended by this interface, if the class is an interface. -
.getClassesImplementing(String interfaceName | Class<?> interfaceRef)
returns a list of classes that implement (or have superclasses that implement) the given interface (or one of its subinterfaces). -
.getClassesWithAnnotation(String annotationClassName | Class<? extends Annotation> annotationClassRef)
returns a list of classes with the given class annotation or meta-annotation. -
.getClassesWithAnyAnnotation(String... annotationClassName | Class<? extends Annotation>... annotationClassRef)
returns a list of classes with any of the the given class annotations or meta-annotations (uses an OR operator). -
.getClassesWithAllAnnotations(String... annotationClassName | Class<? extends Annotation>... annotationClassRef)
returns a list of classes with all of the the given class annotations or meta-annotations (uses an AND operator). -
.getAnnotationsOnClass(String className)
returns a list of annotations on the named class. (N.B. call.enableAnnotationInfo()
before.scan()
, and call.ignoreClassVisibility()
if you want to scan non-public annotations.) -
.getClassesWithMethodAnnotation(String annotationClassName | Class<? extends Annotation> annotationClassRef)
returns a list of classes that have a method with an annotation of the given type. (N.B. call.enableAnnotationInfo()
and.enableMethodInfo()
before.scan()
, and call.ignoreClassVisibility()
and/or.ignoreMethodVisibility()
if you want to scan non-public annotations and/or non-public methods.) -
.getClassesWithMethodParameterAnnotation(String paramAnnotationClassName | Class<? extends Annotation> paramAnnotationClassRef)
returns a list of classes that have a method with a method parameter annotation of the given type. (N.B. call.enableAnnotationInfo()
and.enableMethodInfo()
before.scan()
, and call.ignoreClassVisibility()
and/or.ignoreMethodVisibility()
if you want to scan non-public annotations and/or non-public methods.) -
.getClassesWithFieldAnnotation(String annotationClassName | Class<? extends Annotation> annotationClassRef)
returns a list of classes that have a field with an annotation of the given type. (N.B. call.enableAnnotationInfo()
and.enableFieldInfo()
before.scan()
, and call.ignoreClassVisibility()
and/or.ignoreFieldVisibility()
if you want to scan non-public annotations and/or non-public fields.)
-
-
Querying for a specific named class:
-
Finding all inter-class dependencies: The following methods enable you to find dependencies between classes, by looking for class references in superclasses, interfaces, methods, fields, annotations, local variables, intermediate values within a method's code, concrete type parameters, etc.
💡 Call
ClassGraph ClassGraph#enableInterClassDependencies()
before#scan()
to enable the following methods; you can also callClassGraph#enableExternalClasses()
if you want non-accepted classes in the results.💡 See also
ClassInfo#getClassDependencies()
andClassInfoList#generateGraphVizDotFileFromClassDependencies()
.-
ScanResult#getClassDependencyMap()
returns aMap<ClassInfo, ClassInfoList>
mapping a class to the classes it depends upon. -
ScanResult#getReverseClassDependencyMap()
returns aMap<ClassInfo, ClassInfoList>
mapping a class to the classes that depend upon it.
-
-
Packages:
-
.getPackageInfo()
returns aPackageInfoList
ofPackageInfo
objects for all packages found while scanning. -
.getPackageInfo(String packageName)
returns thePackageInfo
object for the named package, or null if the package was not found.
-
-
Modules:
-
.getModuleInfo()
returns aModuleInfoList
ofModuleInfo
objects for all modules found while scanning. -
.getModuleInfo(String moduleName)
returns theModuleInfo
object for the named module, or null if the module was not found.
-
-
Resources: Except where indicated, these methods return a
ResourceList
consisting ofResource
objects for all the relevant file resources found in accepted paths or packages during the scan.💡 A
ResourceList
can be further filtered by calling.filter(ResourceFilter)
.-
.getAllResources()
returns a list of allResource
objects (including both classfiles an non-classfiles) found in accepted packages during the scan. -
.getAllResourcesAsMap()
returns aMap<String, ResourceList>
mapping from a resource path toResource
for all resources (classfiles and non-classfiles) found in accepted packages during the scan. There can be more that one resource with a given path, if multiple classpath or module path elements contain resources with the same path. -
.getResourcesWithPath(String resourcePath)
returns a list of all resources with the given path (e.g."META-INF/config/config.xml"
) in accepted paths or packages. -
.getResourcesWithPathIgnoringAccept(String resourcePath)
returns a list of all resources with the given path (e.g."META-INF/config/config.xml"
) in any classpath element, ignoring path or package accept criteria (i.e. will return resources whether or not they are accepted, as long as they are not rejected). -
.getResourcesWithLeafName(String leafName)
returns a list of all resources with the given leafname (e.g."config.xml"
) in accepted paths or packages. -
.getResourcesWithExtension(String extension)
returns a list of all resources with the given extension (e.g."xml"
) in accepted paths or packages. -
.getResourcesMatchingWildcard(String wildcardString)
returns a list of all resources with paths matching the given wildcard string (which may contain globs) in accepted paths or packages. The syntax is*
to match zero or more of any character other than/
,**
to match zero or more of any character,?
to match one of any character, and any other Java regex syntax (such as character ranges in square brackets), with the exception of.
, which is escaped before the string is passed to the regex parser. -
.getResourcesMatchingPattern(Pattern pattern)
returns a list of all resources with paths matching the given pattern in accepted paths or packages.
-
-
Serialization to JSON / deserialization from JSON: A
ScanResult
can also be serialized/deserialized for build-time scanning or annotation processing, e.g. for providing Android compatibility, since ClassGraph cannot read Dalvik classfiles. (Note though that if all you need is a list of classes that satisfy certain criteria, it is much more efficient to just store the list of class names of matching classes to a file, rather than the entire serializedScanResult
.) The serialized JSON can also be used for debugging, to quickly examine what ClassGraph found through the scan.-
scanResult.toJSON([int indentWidth])
serializes theScanResult
to JSON. -
ScanResult.fromJSON(String jsonStr)
deserializes from a JSON string, returning aScanResult
.
-
-
Classpath resolution: You can obtain a list of all the classpath elements that were scanned. (N.B. these same four methods are defined in both
ClassGraph
andScanResult
, except that theClassGraph
versions do not extract nested jarfiles, but theScanResult
versions do return URLs/files for nested jars, if any nested jars were extracted during classpath scanning.)-
.getClasspath()
, returns the classpath as a pathString
separated byFile.pathSeparatorChar
. Returns only the base file of each classpath entry (i.e. will not include compound URLs with package roots within a jar, or nested jars within jars, since the URL scheme separator char and the path separator char are both:
on Linux and Mac OS X). -
.getClasspathFiles()
, returns classpath entries as aList<File>
. Returns only the base file of each classpath entry (i.e. will not include compound URLs with package roots within a jar, or nested jars within jars). -
.getClasspathURIs()
, returns classpath entries and modules as aList<URI>
. -
.getClasspathURLs()
, returns classpath as aList<URL>
. Will not includejrt:
URIs for system modules or modules obtained from a jlink'd runtime image, sinceURL
does not support thejrt:
scheme. -
.getModules()
, returns all visible modules as aList<ModuleRef>
ofModuleRef
objects (which is a JDK 7/8-compatible wrapper for JPMS'ModuleReference
). -
.getModulePathInfo()
returns information about the module path, as specified on the commandline using with--module-path
,--add-modules,
--patch-module,--add-exports
,--add-opens
, and--add-reads
, and as also found inAdd-Exports
andAdd-Opens
entries found in manifest files during scanning, as aModulePathInfo
object.
-
-
Freeing resources:
-
.close()
manually frees all resources used by theScanResult
, including deleting any temporary files created by unzipping nested jars. If you don't manually close theScanResult
, then these resources will be freed/deleted by a shutdown hook.
-
Important: The ScanResult
should be assigned in a try-with-resources block or equivalent to free resources allocated during the scan as soon as they are no longer needed (including closing or unmapping open or mapped files, deleting any temporary files that had to be created to read nested jars, closing module references, and freeing memory).
🛑 After the
ScanResult
is closed, any further calls to its methods will throw anIllegalArgumentException
. This also applies to many methods in other objects obtained from theScanResult
, such asClassInfo
,FieldInfo
,MethodInfo
, etc. -- so make sure you extract all the information you need from theScanResult
within the try-with-resources block, and store it in your own data structures, rather than keeping references to objects provided by ClassGraph outside the try-with-resources block.
try (ScanResult scanResult = new ClassGraph().scan()) {
// Use scanResult here
}
ClassGraph().scan().use { scanResult ->
// Use scanResult here
}
new ClassGraph().scan().withCloseable { scanResult ->
// Use scanResult here
}
Scala does not yet have try-with-resources. You will need to close the ScanResult
in a finally
block. It is best to put val scanResult = ...
inside a block too, so that the reference is not still visible after the finally
block is executed.
{
val scanResult = new ClassGraph().scan()
try {
// Use scanResult here
} finally {
scanResult.close()
}
}
If you want to close all open (unclosed) ScanResult
instances at once, you can call the static method ScanResult.closeAll()
. To be safe (to ensure you don't leak any resources), you might want to call this on container unload/destroy in a containerized runtime.
Note that if you call ScanResult.closeAll()
, you need to ensure that the lifecycle of the classloader matches the lifecycle of your application, or that two concurrent applications don't share the same classloader, since this is a static method -- otherwise one application might close another application's ScanResult
instances while they are still in use.