-
-
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 theScanResultin a try-with-resources block -- seeScanResultlifecycle 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 theClassInfoobject 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
ClassInfoListofClassInfoobjects representing the classes.💡 A
ClassInfoListcan 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 toClassInfofor 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 allEnumclasses. -
.getAllRecords()returns a list of allrecordtypes (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 aPackageInfoListofPackageInfoobjects for all packages found while scanning. -
.getPackageInfo(String packageName)returns thePackageInfoobject for the named package, or null if the package was not found.
-
-
Modules:
-
.getModuleInfo()returns aModuleInfoListofModuleInfoobjects for all modules found while scanning. -
.getModuleInfo(String moduleName)returns theModuleInfoobject for the named module, or null if the module was not found.
-
-
Resources: Except where indicated, these methods return a
ResourceListconsisting ofResourceobjects for all the relevant file resources found in accepted paths or packages during the scan.💡 A
ResourceListcan be further filtered by calling.filter(ResourceFilter).-
.getAllResources()returns a list of allResourceobjects (including both classfiles an non-classfiles) found in accepted packages during the scan. -
.getAllResourcesAsMap()returns aMap<String, ResourceList>mapping from a resource path toResourcefor 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
ScanResultcan 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 theScanResultto 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
ClassGraphandScanResult, except that theClassGraphversions do not extract nested jarfiles, but theScanResultversions do return URLs/files for nested jars, if any nested jars were extracted during classpath scanning.)-
.getClasspath(), returns the classpath as a pathStringseparated 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, sinceURLdoes not support thejrt:scheme. -
.getModules(), returns all visible modules as aList<ModuleRef>ofModuleRefobjects (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-ExportsandAdd-Opensentries found in manifest files during scanning, as aModulePathInfoobject.
-
-
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
ScanResultis 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 theScanResultwithin 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.