CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-github-classgraph--classgraph

The uber-fast, ultra-lightweight classpath and module scanner for JVM languages.

Pending
Overview
Eval results
Files

class-info.mddocs/

Class Metadata

The ClassGraph library provides comprehensive metadata about classes through the ClassInfo hierarchy. This includes detailed information about classes, methods, fields, annotations, and their relationships.

ClassInfo - Core Class Metadata

import io.github.classgraph.ClassInfo;
import io.github.classgraph.MethodInfo;
import io.github.classgraph.FieldInfo;
import io.github.classgraph.AnnotationInfo;
import io.github.classgraph.ClassTypeSignature;
import io.github.classgraph.PackageInfo;
import io.github.classgraph.ModuleInfo;
import java.util.List;

Basic Class Information

// Get ClassInfo from ScanResult
ClassInfo classInfo = scanResult.getClassInfo("com.example.MyClass");

if (classInfo != null) {
    // Basic naming and location
    String name = classInfo.getName();                    // "com.example.MyClass"
    String simpleName = classInfo.getSimpleName();       // "MyClass"  
    String packageName = classInfo.getPackageName();     // "com.example"
    
    // Container information
    PackageInfo packageInfo = classInfo.getPackageInfo();
    ModuleInfo moduleInfo = classInfo.getModuleInfo();   // null if not in module
    
    // External class flag
    boolean isExternal = classInfo.isExternalClass();    // true if outside scan scope
}

Classfile and Source Information

// Classfile version information
int majorVersion = classInfo.getClassfileMajorVersion();  // e.g., 55 for Java 11
int minorVersion = classInfo.getClassfileMinorVersion();  // Usually 0

// Source file information
String sourceFile = classInfo.getSourceFile();           // e.g., "MyClass.java"

Modifiers and Type Classification

// Access modifiers
int modifiers = classInfo.getModifiers();
String modifiersStr = classInfo.getModifiersStr();       // "public final"

// Visibility checks
boolean isPublic = classInfo.isPublic();
boolean isPrivate = classInfo.isPrivate();
boolean isProtected = classInfo.isProtected();
boolean isPackageVisible = classInfo.isPackageVisible();

// Modifier checks  
boolean isAbstract = classInfo.isAbstract();
boolean isFinal = classInfo.isFinal();
boolean isStatic = classInfo.isStatic();
boolean isSynthetic = classInfo.isSynthetic();

// Type classification
boolean isInterface = classInfo.isInterface();
boolean isAnnotation = classInfo.isAnnotation();
boolean isEnum = classInfo.isEnum();
boolean isRecord = classInfo.isRecord();              // JDK 14+
boolean isStandardClass = classInfo.isStandardClass(); // Not interface/annotation/enum
boolean isArrayClass = classInfo.isArrayClass();

// Class nesting
boolean isInnerClass = classInfo.isInnerClass();
boolean isOuterClass = classInfo.isOuterClass();
boolean isAnonymousInnerClass = classInfo.isAnonymousInnerClass();

Class Relationship Checks

// Inheritance checks
boolean extendsClass = classInfo.extendsSuperclass("java.util.AbstractList");
boolean extendsByClass = classInfo.extendsSuperclass(AbstractList.class);

// Interface implementation checks  
boolean implementsInterface = classInfo.implementsInterface("java.util.List");
boolean implementsByClass = classInfo.implementsInterface(List.class);

// Annotation checks
boolean hasAnnotation = classInfo.hasAnnotation("javax.persistence.Entity");
boolean hasAnnotationByClass = classInfo.hasAnnotation(Entity.class);

Class Hierarchy Information

// Superclass hierarchy
ClassInfo superclass = classInfo.getSuperclass();           // Direct superclass
ClassInfoList superclasses = classInfo.getSuperclasses();   // Full hierarchy

// Subclass relationships  
ClassInfoList subclasses = classInfo.getSubclasses();       // Direct and indirect

// Interface relationships
ClassInfoList interfaces = classInfo.getInterfaces();                    // Implemented interfaces
ClassInfoList implementingClasses = classInfo.getClassesImplementing();  // Classes implementing this interface (if interface)

// Inner/outer class relationships
ClassInfoList innerClasses = classInfo.getInnerClasses();
ClassInfoList outerClasses = classInfo.getOuterClasses();

Field Information

Field Discovery and Access

// Check for field existence
boolean hasDeclaredField = classInfo.hasDeclaredField("userName");
boolean hasField = classInfo.hasField("userName");  // Including inherited

// Get field information
FieldInfo declaredField = classInfo.getDeclaredFieldInfo("userName");
FieldInfo field = classInfo.getFieldInfo("userName");  // Including inherited

// Get all fields
FieldInfoList declaredFields = classInfo.getDeclaredFieldInfo();
FieldInfoList allFields = classInfo.getFieldInfo();  // Including inherited

// Enum-specific field access
if (classInfo.isEnum()) {
    FieldInfoList enumConstants = classInfo.getEnumConstants();
    List<Object> enumConstantObjects = classInfo.getEnumConstantObjects();
}

Field Annotation Queries

// Check for field annotations
boolean hasDeclaredFieldAnnotation = classInfo.hasDeclaredFieldAnnotation("javax.persistence.Column");
boolean hasFieldAnnotation = classInfo.hasFieldAnnotation("javax.persistence.Column");  // Including inherited

// Field annotation with class types
boolean hasColumnAnnotation = classInfo.hasFieldAnnotation(Column.class);

FieldInfo Details

FieldInfo fieldInfo = classInfo.getDeclaredFieldInfo("userName");

if (fieldInfo != null) {
    // Basic field information
    String name = fieldInfo.getName();
    String className = fieldInfo.getClassName();
    ClassInfo fieldClassInfo = fieldInfo.getClassInfo();
    
    // Modifiers
    int modifiers = fieldInfo.getModifiers();
    String modifiersStr = fieldInfo.getModifiersStr();
    boolean isTransient = fieldInfo.isTransient();
    boolean isEnum = fieldInfo.isEnum();
    
    // Type information
    TypeSignature typeDescriptor = fieldInfo.getTypeDescriptor();
    TypeSignature typeSignature = fieldInfo.getTypeSignature();  // Generic signature
    TypeSignature typeSignatureOrDescriptor = fieldInfo.getTypeSignatureOrTypeDescriptor();
    
    // Constant value (for static final fields)
    Object constantValue = fieldInfo.getConstantInitializerValue();
    
    // Annotation information
    AnnotationInfoList annotations = fieldInfo.getAnnotationInfo();
    
    // Load actual Field via reflection
    Field reflectionField = fieldInfo.loadClassAndGetField();
}

Method Information

Method Discovery and Access

// Check for method existence
boolean hasDeclaredMethod = classInfo.hasDeclaredMethod("getUserName");
boolean hasMethod = classInfo.hasMethod("getUserName");  // Including inherited

// Get methods by name
MethodInfoList declaredMethods = classInfo.getDeclaredMethodInfo("getUserName");
MethodInfoList methods = classInfo.getMethodInfo("getUserName");  // Including inherited

// Get all methods
MethodInfoList allDeclaredMethods = classInfo.getDeclaredMethodInfo();
MethodInfoList allMethods = classInfo.getMethodInfo();  // Including inherited

// Constructor access
MethodInfoList declaredConstructors = classInfo.getDeclaredConstructorInfo();
MethodInfoList constructors = classInfo.getConstructorInfo();

// Combined method and constructor access
MethodInfoList allDeclaredMethodsAndConstructors = classInfo.getDeclaredMethodAndConstructorInfo();
MethodInfoList allMethodsAndConstructors = classInfo.getMethodAndConstructorInfo();

Method Annotation Queries

// Check for method annotations
boolean hasDeclaredMethodAnnotation = classInfo.hasDeclaredMethodAnnotation("org.junit.Test");
boolean hasMethodAnnotation = classInfo.hasMethodAnnotation("org.junit.Test");  // Including inherited

// Parameter annotation checks
boolean hasDeclaredParamAnnotation = classInfo.hasDeclaredMethodParameterAnnotation("javax.validation.Valid");
boolean hasParamAnnotation = classInfo.hasMethodParameterAnnotation("javax.validation.Valid");  // Including inherited

MethodInfo Details

MethodInfo methodInfo = classInfo.getDeclaredMethodInfo("processUser").get(0);

if (methodInfo != null) {
    // Basic method information
    String name = methodInfo.getName();
    String className = methodInfo.getClassName();
    ClassInfo methodClassInfo = methodInfo.getClassInfo();
    
    // Modifiers
    int modifiers = methodInfo.getModifiers();
    String modifiersStr = methodInfo.getModifiersStr();
    
    // Method type checks
    boolean isConstructor = methodInfo.isConstructor();
    boolean isSynchronized = methodInfo.isSynchronized();
    boolean isBridge = methodInfo.isBridge();
    boolean isVarArgs = methodInfo.isVarArgs();
    boolean isNative = methodInfo.isNative();
    boolean isAbstract = methodInfo.isAbstract();
    boolean isStrict = methodInfo.isStrict();
    boolean hasBody = methodInfo.hasBody();
    boolean isDefault = methodInfo.isDefault();  // Default interface method
    
    // Type signatures
    MethodTypeSignature typeDescriptor = methodInfo.getTypeDescriptor();
    MethodTypeSignature typeSignature = methodInfo.getTypeSignature();
    MethodTypeSignature typeSignatureOrDescriptor = methodInfo.getTypeSignatureOrTypeDescriptor();
    
    // Exception information
    ClassInfoList thrownExceptions = methodInfo.getThrownExceptions();
    String[] thrownExceptionNames = methodInfo.getThrownExceptionNames();
    
    // Debug information
    int minLineNum = methodInfo.getMinLineNum();
    int maxLineNum = methodInfo.getMaxLineNum();
    
    // Parameter information
    MethodParameterInfo[] parameters = methodInfo.getParameterInfo();
    boolean hasParamAnnotation = methodInfo.hasParameterAnnotation(Valid.class);
    
    // Annotation information
    AnnotationInfoList annotations = methodInfo.getAnnotationInfo();
    
    // Load actual Method via reflection
    Method reflectionMethod = methodInfo.loadClassAndGetMethod();
}

Method Parameter Information

MethodParameterInfo[] parameters = methodInfo.getParameterInfo();

for (MethodParameterInfo param : parameters) {
    // Basic parameter info
    MethodInfo containingMethod = param.getMethodInfo();
    String paramName = param.getName();  // May be null if not available
    
    // Parameter modifiers
    int modifiers = param.getModifiers();
    String modifiersStr = param.getModifiersStr();
    
    // Type information
    TypeSignature typeSignature = param.getTypeSignature();
    TypeSignature typeDescriptor = param.getTypeDescriptor();
    TypeSignature typeSignatureOrDescriptor = param.getTypeSignatureOrTypeDescriptor();
    
    // Parameter annotations
    AnnotationInfoList annotations = param.getAnnotationInfo();
    AnnotationInfo validAnnotation = param.getAnnotationInfo(Valid.class);
}

Annotation Information

Class Annotations

// Get all annotations on a class
AnnotationInfoList classAnnotations = classInfo.getAnnotationInfo();

// Get specific annotation
AnnotationInfo entityAnnotation = classInfo.getAnnotationInfo("javax.persistence.Entity");
AnnotationInfo entityByClass = classInfo.getAnnotationInfo(Entity.class);

// Repeatable annotations (Java 8+)
AnnotationInfoList repeatableAnnotations = classInfo.getAnnotationInfoRepeatable(Repeatable.class);

// Default annotation parameter values
AnnotationParameterValueList defaults = classInfo.getAnnotationDefaultParameterValues();

// Get classes annotated with this annotation (if this class is an annotation)
ClassInfoList annotatedClasses = classInfo.getClassesWithAnnotation();

AnnotationInfo Details

AnnotationInfo annotation = classInfo.getAnnotationInfo(Entity.class);

if (annotation != null) {
    // Basic annotation information  
    String name = annotation.getName();
    boolean isInherited = annotation.isInherited();
    
    // Parameter values
    AnnotationParameterValueList defaultValues = annotation.getDefaultParameterValues();
    AnnotationParameterValueList actualValues = annotation.getParameterValues();
    AnnotationParameterValueList allValues = annotation.getParameterValues(true);  // Including defaults
    
    // Get related class information
    ClassInfo annotationClassInfo = annotation.getClassInfo();
    
    // Load and instantiate annotation
    Annotation annotationInstance = annotation.loadClassAndInstantiate();
}

Annotation Parameter Values

AnnotationParameterValueList paramValues = annotation.getParameterValues();

for (AnnotationParameterValue param : paramValues) {
    String paramName = param.getName();
    Object value = param.getValue();
    
    // Value can be various types:
    // - String, primitive types, Class references
    // - Arrays of the above
    // - Nested annotations (AnnotationInfo)
    // - Enum values (AnnotationEnumValue)
    
    if (value instanceof String) {
        String stringValue = (String) value;
    } else if (value instanceof AnnotationEnumValue) {
        AnnotationEnumValue enumValue = (AnnotationEnumValue) value;
        String enumClassName = enumValue.getClassName();
        String enumConstantName = enumValue.getValueName();
        Object actualEnumValue = enumValue.loadClassAndReturnEnumValue();
    } else if (value instanceof AnnotationInfo) {
        AnnotationInfo nestedAnnotation = (AnnotationInfo) value;
        // Process nested annotation...
    }
}

// Direct parameter value access
Object tableNameValue = paramValues.getValue("name");

Type Signatures and Generics

ClassInfo provides access to complete generic type information:

// Get type signature information
String typeSignatureStr = classInfo.getTypeSignatureStr();
ClassTypeSignature typeSignature = classInfo.getTypeSignature();
ClassTypeSignature typeSignatureOrDescriptor = classInfo.getTypeSignatureOrTypeDescriptor();
ClassTypeSignature typeDescriptor = classInfo.getTypeDescriptor();  // Synthetic descriptor

if (typeSignature != null) {
    // Generic type parameters
    List<TypeParameter> typeParameters = typeSignature.getTypeParameters();
    
    // Superclass with generics
    ClassRefTypeSignature superclassSignature = typeSignature.getSuperclassSignature();
    
    // Implemented interfaces with generics
    List<ClassRefTypeSignature> superinterfaceSignatures = typeSignature.getSuperinterfaceSignatures();
}

Location and Resources

Classpath Element Information

// Get classpath element containing this class
URI classpathElementURI = classInfo.getClasspathElementURI();
URL classpathElementURL = classInfo.getClasspathElementURL();
File classpathElementFile = classInfo.getClasspathElementFile();

// Module information (if applicable)
ModuleRef moduleRef = classInfo.getModuleRef();

// Get the resource for the class file itself
Resource classResource = classInfo.getResource();

Class Loading

Safe Class Loading

// Load class with error handling
try {
    Class<?> clazz = classInfo.loadClass(false);  // false = don't initialize
    System.out.println("Loaded: " + clazz.getName());
} catch (Exception e) {
    System.err.println("Failed to load class: " + e.getMessage());
}

// Load without error handling (throws on failure)
Class<?> clazz = classInfo.loadClass();

// Load and cast with type safety
Class<? extends Service> serviceClass = classInfo.loadClass(Service.class, false);
Class<? extends Service> serviceClassThrow = classInfo.loadClass(Service.class);  // Throws on error

Practical Examples

Find Service Implementations with Configuration

ClassInfoList serviceImpls = scanResult.getClassesImplementing("com.example.Service");

for (ClassInfo serviceClass : serviceImpls) {
    // Check if it's a concrete implementation
    if (!serviceClass.isAbstract() && !serviceClass.isInterface()) {
        System.out.println("Service Implementation: " + serviceClass.getName());
        
        // Check for configuration annotations
        AnnotationInfo configAnnotation = serviceClass.getAnnotationInfo("com.example.Configuration");
        if (configAnnotation != null) {
            String configName = (String) configAnnotation.getParameterValues().getValue("name");
            System.out.println("  Configuration: " + configName);
        }
        
        // Check for required dependencies via constructor parameters
        MethodInfoList constructors = serviceClass.getDeclaredConstructorInfo();
        for (MethodInfo constructor : constructors) {
            if (constructor.isPublic()) {
                MethodParameterInfo[] params = constructor.getParameterInfo();
                System.out.println("  Constructor dependencies:");
                for (MethodParameterInfo param : params) {
                    TypeSignature paramType = param.getTypeSignature();
                    System.out.println("    " + paramType.toString());
                }
            }
        }
    }
}

Analyze REST Controller Methods

ClassInfoList controllers = scanResult.getClassesWithAnnotation("org.springframework.web.bind.annotation.RestController");

for (ClassInfo controller : controllers) {
    System.out.println("Controller: " + controller.getName());
    
    // Find request mapping methods
    MethodInfoList requestMethods = controller.getDeclaredMethodInfo()
        .filter(method -> 
            method.hasAnnotation("org.springframework.web.bind.annotation.GetMapping") ||
            method.hasAnnotation("org.springframework.web.bind.annotation.PostMapping") ||
            method.hasAnnotation("org.springframework.web.bind.annotation.PutMapping") ||
            method.hasAnnotation("org.springframework.web.bind.annotation.DeleteMapping"));
    
    for (MethodInfo method : requestMethods) {
        System.out.println("  Endpoint: " + method.getName());
        
        // Extract HTTP method and path
        AnnotationInfo getMapping = method.getAnnotationInfo("org.springframework.web.bind.annotation.GetMapping");
        if (getMapping != null) {
            Object pathValue = getMapping.getParameterValues().getValue("value");
            if (pathValue instanceof String[]) {
                String[] paths = (String[]) pathValue;
                System.out.println("    GET " + Arrays.toString(paths));
            }
        }
        
        // Analyze parameters for validation
        MethodParameterInfo[] params = method.getParameterInfo();
        for (MethodParameterInfo param : params) {
            if (param.hasAnnotation("javax.validation.Valid")) {
                System.out.println("    Validated parameter: " + param.getTypeSignature());
            }
        }
    }
}

The ClassInfo API provides comprehensive access to all aspects of class metadata, enabling sophisticated analysis and code generation capabilities while maintaining type safety and performance.

Install with Tessl CLI

npx tessl i tessl/maven-io-github-classgraph--classgraph

docs

class-info.md

index.md

querying.md

resources.md

scanning.md

type-signatures.md

tile.json