Class Classfile
java.lang.Object
io.github.classgraph.Classfile
A classfile binary format parser. Implements its own buffering to avoid the overhead of using DataInputStream.
This class should only be used by a single thread at a time, but can be re-used to scan multiple classfiles in
sequence, to avoid re-allocating buffer memory.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static classClass containment.(package private) static classThrown when a classfile's contents are not in the correct format.(package private) static interface(package private) static interface(package private) static classThrown when a classfile needs to be skipped.(package private) static interface(package private) static class -
Field Summary
FieldsModifier and TypeFieldDescriptionThe names of accepted classes found in the classpath while scanning paths within classpath elements.private List<Scanner.ClassfileScanWorkUnit> Any additional work units scheduled for scanning.private AnnotationParameterValueListAnnotation default parameter values.private AnnotationInfoListThe class annotations.private List<Classfile.ClassContainment> Class containment entries.private final ResourceThe classfile resource.private intThe class modifiers.private StringThe name of the class.The names of external (non-accepted) classes scheduled for extended scanning (where scanning is extended upwards to superclasses, interfaces and annotations).private final ClasspathElementThe classpath element that contains this classfile.private final List<ClasspathElement> The classpath order.The type annotation decorators for theClassTypeSignatureinstance.private intThe number of constant pool entries plus one.private int[]The byte offset for the beginning of each entry in the constant pool.private int[]The tag (type) for each entry in the constant pool.private FieldInfoListThe field info list.private StringThe fully qualified name of the defining method.The implemented interfaces.private int[]The indirection index for String/Class entries in the constant pool.private booleanWhether this class is an annotation.private final booleanWhether this is an external class.private booleanWhether this class is an interface.private booleanWhether this class is a record.private intThe major version of the classfile format.private MethodInfoListThe method info list.private intThe minor version of the classfile format.private static final AnnotationInfo[]An empty array for the case where there are no annotations.private ClassfileReaderTheClassfileReaderfor the current classfile.Referenced class names.private final StringThe relative path to the classfile (should correspond to className).private final ScanSpecThe scan spec.private StringThe source file, such as Classfile.javaprivate final ConcurrentHashMap<String, String> The string intern map.private StringThe superclass name.private StringThe type signature. -
Constructor Summary
ConstructorsConstructorDescriptionClassfile(ClasspathElement classpathElement, List<ClasspathElement> classpathOrder, Set<String> acceptedClassNamesFound, Set<String> classNamesScheduledForExtendedScanning, String relativePath, Resource classfileResource, boolean isExternalClass, ConcurrentHashMap<String, String> stringInternMap, WorkQueue<Scanner.ClassfileScanWorkUnit> workQueue, ScanSpec scanSpec, LogNode log) Directly examine contents of classfile binary header to determine annotations, implemented interfaces, the super-class etc. -
Method Summary
Modifier and TypeMethodDescriptionprivate booleanconstantPoolStringEquals(int cpIdx, String asciiStr) Compare a string in the constant pool with a given ASCII string, without constructing the constant pool String object.private intcpReadInt(int cpIdx) Read an int from the constant pool.private longcpReadLong(int cpIdx) Read a long from the constant pool.private voidCheck if scanning needs to be extended upwards to an external superclass, interface or annotation.private voidextendScanningUpwardsFromAnnotationParameterValues(Object annotationParamVal, LogNode log) Check if scanning needs to be extended upwards from an annotation parameter value.private StringgetConstantPoolClassDescriptor(int cpIdx) Get a string from the constant pool representing an internal string descriptor for a class name ("Lcom/xyz/MyClass;"), and interpret it as a class name by replacing '/' with '.', and removing the leading "L" and the trailing ";".private StringgetConstantPoolClassName(int cpIdx) Get a string from the constant pool, and interpret it as a class name by replacing '/' with '.'.private StringgetConstantPoolString(int cpIdx) Get a string from the constant pool.private StringgetConstantPoolString(int cpIdx, boolean replaceSlashWithDot, boolean stripLSemicolon) Get a string from the constant pool, optionally replacing '/' with '.'.private StringgetConstantPoolString(int cpIdx, int subFieldIdx) Get a string from the constant pool.private bytegetConstantPoolStringFirstByte(int cpIdx) Get the first UTF8 byte of a string in the constant pool, or '\0' if the string is null or empty.private intgetConstantPoolStringOffset(int cpIdx, int subFieldIdx) Get the byte offset within the buffer of a string from the constant pool, or 0 for a null string.private ObjectgetFieldConstantPoolValue(int tag, char fieldTypeDescriptorFirstChar, int cpIdx) Get a field constant from the constant pool.private StringIntern a string.(package private) voidlink(Map<String, ClassInfo> classNameToClassInfo, Map<String, PackageInfo> packageNameToPackageInfo, Map<String, ModuleInfo> moduleNameToModuleInfo) Link classes.private AnnotationInfoRead annotation entry from classfile.private ObjectRead annotation element value from classfile.private voidRead basic class information.private voidRead class attributes.private voidRead constant pool entries.private voidRead the class' fields.private voidRead the class' interfaces.private voidRead the class' methods.private List<Classfile.TypePathNode> private voidscheduleScanningIfExternalClass(String className, String relationship, LogNode log) Extend scanning to a superclass, interface or annotation.
-
Field Details
-
reader
TheClassfileReaderfor the current classfile. -
classpathElement
The classpath element that contains this classfile. -
classpathOrder
The classpath order. -
relativePath
The relative path to the classfile (should correspond to className). -
classfileResource
The classfile resource. -
stringInternMap
The string intern map. -
className
The name of the class. -
minorVersion
private int minorVersionThe minor version of the classfile format. -
majorVersion
private int majorVersionThe major version of the classfile format. -
isExternalClass
private final boolean isExternalClassWhether this is an external class. -
classModifiers
private int classModifiersThe class modifiers. -
isInterface
private boolean isInterfaceWhether this class is an interface. -
isRecord
private boolean isRecordWhether this class is a record. -
isAnnotation
private boolean isAnnotationWhether this class is an annotation. -
superclassName
The superclass name. (can be null if no superclass, or if superclass is rejected.) -
implementedInterfaces
-
classAnnotations
The class annotations. -
fullyQualifiedDefiningMethodName
The fully qualified name of the defining method. -
classContainmentEntries
Class containment entries. -
annotationParamDefaultValues
Annotation default parameter values. -
refdClassNames
-
fieldInfoList
The field info list. -
methodInfoList
The method info list. -
typeSignatureStr
The type signature. -
sourceFile
The source file, such as Classfile.java -
classTypeAnnotationDecorators
The type annotation decorators for theClassTypeSignatureinstance. -
acceptedClassNamesFound
-
classNamesScheduledForExtendedScanning
-
additionalWorkUnits
Any additional work units scheduled for scanning. -
scanSpec
The scan spec. -
cpCount
private int cpCountThe number of constant pool entries plus one. -
entryOffset
private int[] entryOffsetThe byte offset for the beginning of each entry in the constant pool. -
entryTag
private int[] entryTagThe tag (type) for each entry in the constant pool. -
indirectStringRefs
private int[] indirectStringRefsThe indirection index for String/Class entries in the constant pool. -
NO_ANNOTATIONS
An empty array for the case where there are no annotations.
-
-
Constructor Details
-
Classfile
Classfile(ClasspathElement classpathElement, List<ClasspathElement> classpathOrder, Set<String> acceptedClassNamesFound, Set<String> classNamesScheduledForExtendedScanning, String relativePath, Resource classfileResource, boolean isExternalClass, ConcurrentHashMap<String, String> stringInternMap, WorkQueue<Scanner.ClassfileScanWorkUnit> workQueue, ScanSpec scanSpec, LogNode log) throws IOException, Classfile.ClassfileFormatException, Classfile.SkipClassExceptionDirectly examine contents of classfile binary header to determine annotations, implemented interfaces, the super-class etc. Creates a new ClassInfo object, and adds it to classNameToClassInfoOut. Assumes classpath masking has already been performed, so that only one class of a given name will be added.- Parameters:
classpathElement- the classpath elementclasspathOrder- the classpath orderacceptedClassNamesFound- the names of accepted classes found in the classpath while scanning paths within classpath elements.classNamesScheduledForExtendedScanning- the names of external (non-accepted) classes scheduled for extended scanning (where scanning is extended upwards to superclasses, interfaces and annotations).relativePath- the relative pathclassfileResource- the classfile resourceisExternalClass- if this is an external classstringInternMap- the string intern mapworkQueue- the work queuescanSpec- the scan speclog- the log- Throws:
IOException- If an IO exception occurs.Classfile.ClassfileFormatException- If a problem occurs while parsing the classfile.Classfile.SkipClassException- if the classfile needs to be skipped (e.g. the class is non-public, and ignoreClassVisibility is false)
-
-
Method Details
-
scheduleScanningIfExternalClass
-
extendScanningUpwardsFromAnnotationParameterValues
private void extendScanningUpwardsFromAnnotationParameterValues(Object annotationParamVal, LogNode log) Check if scanning needs to be extended upwards from an annotation parameter value.- Parameters:
annotationParamVal- theAnnotationInfoobject for an annotation, or for an annotation parameter value.log- the log
-
extendScanningUpwards
Check if scanning needs to be extended upwards to an external superclass, interface or annotation.- Parameters:
log- the log
-
link
void link(Map<String, ClassInfo> classNameToClassInfo, Map<String, PackageInfo> packageNameToPackageInfo, Map<String, ModuleInfo> moduleNameToModuleInfo) Link classes. Not threadsafe, should be run in a single-threaded context.- Parameters:
classNameToClassInfo- map from class name to class infopackageNameToPackageInfo- map from package name to package infomoduleNameToModuleInfo- map from module name to module info
-
intern
-
getConstantPoolStringOffset
private int getConstantPoolStringOffset(int cpIdx, int subFieldIdx) throws Classfile.ClassfileFormatException Get the byte offset within the buffer of a string from the constant pool, or 0 for a null string.- Parameters:
cpIdx- the constant pool indexsubFieldIdx- should be 0 for CONSTANT_Utf8, CONSTANT_Class and CONSTANT_String, and for CONSTANT_NameAndType_info, fetches the name for value 0, or the type descriptor for value 1.- Returns:
- the constant pool string offset
- Throws:
Classfile.ClassfileFormatException- If a problem is detected
-
getConstantPoolString
private String getConstantPoolString(int cpIdx, boolean replaceSlashWithDot, boolean stripLSemicolon) throws Classfile.ClassfileFormatException, IOException Get a string from the constant pool, optionally replacing '/' with '.'.- Parameters:
cpIdx- the constant pool indexreplaceSlashWithDot- if true, replace slash with dot in the result.stripLSemicolon- if true, strip 'L' from the beginning and ';' from the end before returning (for class reference constants)- Returns:
- the constant pool string
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
getConstantPoolString
private String getConstantPoolString(int cpIdx, int subFieldIdx) throws Classfile.ClassfileFormatException, IOException Get a string from the constant pool.- Parameters:
cpIdx- the constant pool indexsubFieldIdx- should be 0 for CONSTANT_Utf8, CONSTANT_Class and CONSTANT_String, and for CONSTANT_NameAndType_info, fetches the name for value 0, or the type descriptor for value 1.- Returns:
- the constant pool string
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
getConstantPoolString
private String getConstantPoolString(int cpIdx) throws Classfile.ClassfileFormatException, IOException Get a string from the constant pool.- Parameters:
cpIdx- the constant pool index- Returns:
- the constant pool string
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
getConstantPoolStringFirstByte
private byte getConstantPoolStringFirstByte(int cpIdx) throws Classfile.ClassfileFormatException, IOException Get the first UTF8 byte of a string in the constant pool, or '\0' if the string is null or empty.- Parameters:
cpIdx- the constant pool index- Returns:
- the first byte of the constant pool string
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
getConstantPoolClassName
private String getConstantPoolClassName(int cpIdx) throws Classfile.ClassfileFormatException, IOException Get a string from the constant pool, and interpret it as a class name by replacing '/' with '.'.- Parameters:
cpIdx- the constant pool index- Returns:
- the constant pool class name
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
getConstantPoolClassDescriptor
private String getConstantPoolClassDescriptor(int cpIdx) throws Classfile.ClassfileFormatException, IOException Get a string from the constant pool representing an internal string descriptor for a class name ("Lcom/xyz/MyClass;"), and interpret it as a class name by replacing '/' with '.', and removing the leading "L" and the trailing ";".- Parameters:
cpIdx- the constant pool index- Returns:
- the constant pool class descriptor
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
constantPoolStringEquals
private boolean constantPoolStringEquals(int cpIdx, String asciiStr) throws Classfile.ClassfileFormatException, IOException Compare a string in the constant pool with a given ASCII string, without constructing the constant pool String object.- Parameters:
cpIdx- the constant pool indexasciiStr- the ASCII string to compare to- Returns:
- true, if successful
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
cpReadInt
Read an int from the constant pool.- Parameters:
cpIdx- the constant pool index.- Returns:
- the int
- Throws:
IOException- If an I/O exception occurred.
-
cpReadLong
Read a long from the constant pool.- Parameters:
cpIdx- the constant pool index.- Returns:
- the long
- Throws:
IOException- If an I/O exception occurred.
-
getFieldConstantPoolValue
private Object getFieldConstantPoolValue(int tag, char fieldTypeDescriptorFirstChar, int cpIdx) throws Classfile.ClassfileFormatException, IOException Get a field constant from the constant pool.- Parameters:
tag- the tagfieldTypeDescriptorFirstChar- the first char of the field type descriptorcpIdx- the constant pool index- Returns:
- the field constant pool value
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.IOException- If an IO exception occurs.
-
readAnnotation
Read annotation entry from classfile.- Returns:
- the annotation, as an
AnnotationInfoobject. - Throws:
IOException- If an IO exception occurs.
-
readAnnotationElementValue
Read annotation element value from classfile.- Returns:
- the annotation element value
- Throws:
IOException- If an IO exception occurs.
-
readTypePath
- Throws:
IOException
-
readConstantPoolEntries
Read constant pool entries.- Parameters:
log- The log- Throws:
IOException- Signals that an I/O exception has occurred.
-
readBasicClassInfo
private void readBasicClassInfo() throws IOException, Classfile.ClassfileFormatException, Classfile.SkipClassExceptionRead basic class information.- Throws:
IOException- if an I/O exception occurs.Classfile.ClassfileFormatException- if the classfile is incorrectly formatted.Classfile.SkipClassException- if the classfile needs to be skipped (e.g. the class is non-public, and ignoreClassVisibility is false)
-
readInterfaces
Read the class' interfaces.- Throws:
IOException- if an I/O exception occurs.
-
readFields
Read the class' fields.- Throws:
IOException- if an I/O exception occurs.Classfile.ClassfileFormatException- if the classfile is incorrectly formatted.
-
readMethods
Read the class' methods.- Throws:
IOException- if an I/O exception occurs.Classfile.ClassfileFormatException- if the classfile is incorrectly formatted.
-
readClassAttributes
Read class attributes.- Throws:
IOException- if an I/O exception occurs.Classfile.ClassfileFormatException- if the classfile is incorrectly formatted.
-