Package io.github.classgraph
Class Classfile
- java.lang.Object
-
- io.github.classgraph.Classfile
-
class Classfile extends java.lang.ObjectA 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 Classes Modifier and Type Class Description (package private) static classClassfile.ClassContainmentClass containment.(package private) static classClassfile.ClassfileFormatExceptionThrown when a classfile's contents are not in the correct format.(package private) static interfaceClassfile.ClassTypeAnnotationDecorator(package private) static interfaceClassfile.MethodTypeAnnotationDecorator(package private) static classClassfile.SkipClassExceptionThrown when a classfile needs to be skipped.(package private) static interfaceClassfile.TypeAnnotationDecorator(package private) static classClassfile.TypePathNode
-
Field Summary
Fields Modifier and Type Field Description private java.util.Set<java.lang.String>acceptedClassNamesFoundThe names of accepted classes found in the classpath while scanning paths within classpath elements.private java.util.List<Scanner.ClassfileScanWorkUnit>additionalWorkUnitsAny additional work units scheduled for scanning.private AnnotationParameterValueListannotationParamDefaultValuesAnnotation default parameter values.private AnnotationInfoListclassAnnotationsThe class annotations.private java.util.List<Classfile.ClassContainment>classContainmentEntriesClass containment entries.private ResourceclassfileResourceThe classfile resource.private intclassModifiersThe class modifiers.private java.lang.StringclassNameThe name of the class.private java.util.Set<java.lang.String>classNamesScheduledForExtendedScanningThe names of external (non-accepted) classes scheduled for extended scanning (where scanning is extended upwards to superclasses, interfaces and annotations).private ClasspathElementclasspathElementThe classpath element that contains this classfile.private java.util.List<ClasspathElement>classpathOrderThe classpath order.private java.util.List<Classfile.ClassTypeAnnotationDecorator>classTypeAnnotationDecoratorsThe type annotation decorators for theClassTypeSignatureinstance.private intcpCountThe number of constant pool entries plus one.private int[]entryOffsetThe byte offset for the beginning of each entry in the constant pool.private int[]entryTagThe tag (type) for each entry in the constant pool.private FieldInfoListfieldInfoListThe field info list.private java.lang.StringfullyQualifiedDefiningMethodNameThe fully qualified name of the defining method.private java.util.List<java.lang.String>implementedInterfacesThe implemented interfaces.private int[]indirectStringRefsThe indirection index for String/Class entries in the constant pool.private booleanisAnnotationWhether this class is an annotation.private booleanisExternalClassWhether this is an external class.private booleanisInterfaceWhether this class is an interface.private booleanisRecordWhether this class is a record.private intmajorVersionThe major version of the classfile format.private MethodInfoListmethodInfoListThe method info list.private intminorVersionThe minor version of the classfile format.private static AnnotationInfo[]NO_ANNOTATIONSAn empty array for the case where there are no annotations.private ClassfileReaderreaderTheClassfileReaderfor the current classfile.private java.util.Set<java.lang.String>refdClassNamesReferenced class names.private java.lang.StringrelativePathThe relative path to the classfile (should correspond to className).private ScanSpecscanSpecThe scan spec.private java.lang.StringsourceFileThe source file, such as Classfile.javaprivate java.util.concurrent.ConcurrentHashMap<java.lang.String,java.lang.String>stringInternMapThe string intern map.private java.lang.StringsuperclassNameThe superclass name.private java.lang.StringtypeSignatureStrThe type signature.
-
Constructor Summary
Constructors Constructor Description Classfile(ClasspathElement classpathElement, java.util.List<ClasspathElement> classpathOrder, java.util.Set<java.lang.String> acceptedClassNamesFound, java.util.Set<java.lang.String> classNamesScheduledForExtendedScanning, java.lang.String relativePath, Resource classfileResource, boolean isExternalClass, java.util.concurrent.ConcurrentHashMap<java.lang.String,java.lang.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
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private booleanconstantPoolStringEquals(int cpIdx, java.lang.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 voidextendScanningUpwards(LogNode log)Check if scanning needs to be extended upwards to an external superclass, interface or annotation.private voidextendScanningUpwardsFromAnnotationParameterValues(java.lang.Object annotationParamVal, LogNode log)Check if scanning needs to be extended upwards from an annotation parameter value.private java.lang.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 java.lang.StringgetConstantPoolClassName(int cpIdx)Get a string from the constant pool, and interpret it as a class name by replacing '/' with '.'.private java.lang.StringgetConstantPoolString(int cpIdx)Get a string from the constant pool.private java.lang.StringgetConstantPoolString(int cpIdx, boolean replaceSlashWithDot, boolean stripLSemicolon)Get a string from the constant pool, optionally replacing '/' with '.'.private java.lang.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 java.lang.ObjectgetFieldConstantPoolValue(int tag, char fieldTypeDescriptorFirstChar, int cpIdx)Get a field constant from the constant pool.private java.lang.Stringintern(java.lang.String str)Intern a string.(package private) voidlink(java.util.Map<java.lang.String,ClassInfo> classNameToClassInfo, java.util.Map<java.lang.String,PackageInfo> packageNameToPackageInfo, java.util.Map<java.lang.String,ModuleInfo> moduleNameToModuleInfo)Link classes.private AnnotationInforeadAnnotation()Read annotation entry from classfile.private java.lang.ObjectreadAnnotationElementValue()Read annotation element value from classfile.private voidreadBasicClassInfo()Read basic class information.private voidreadClassAttributes()Read class attributes.private voidreadConstantPoolEntries(LogNode log)Read constant pool entries.private voidreadFields()Read the class' fields.private voidreadInterfaces()Read the class' interfaces.private voidreadMethods()Read the class' methods.private java.util.List<Classfile.TypePathNode>readTypePath()private voidscheduleScanningIfExternalClass(java.lang.String className, java.lang.String relationship, LogNode log)Extend scanning to a superclass, interface or annotation.
-
-
-
Field Detail
-
reader
private ClassfileReader reader
TheClassfileReaderfor the current classfile.
-
classpathElement
private final ClasspathElement classpathElement
The classpath element that contains this classfile.
-
classpathOrder
private final java.util.List<ClasspathElement> classpathOrder
The classpath order.
-
relativePath
private final java.lang.String relativePath
The relative path to the classfile (should correspond to className).
-
classfileResource
private final Resource classfileResource
The classfile resource.
-
stringInternMap
private final java.util.concurrent.ConcurrentHashMap<java.lang.String,java.lang.String> stringInternMap
The string intern map.
-
className
private java.lang.String className
The name of the class.
-
minorVersion
private int minorVersion
The minor version of the classfile format.
-
majorVersion
private int majorVersion
The major version of the classfile format.
-
isExternalClass
private final boolean isExternalClass
Whether this is an external class.
-
classModifiers
private int classModifiers
The class modifiers.
-
isInterface
private boolean isInterface
Whether this class is an interface.
-
isRecord
private boolean isRecord
Whether this class is a record.
-
isAnnotation
private boolean isAnnotation
Whether this class is an annotation.
-
superclassName
private java.lang.String superclassName
The superclass name. (can be null if no superclass, or if superclass is rejected.)
-
implementedInterfaces
private java.util.List<java.lang.String> implementedInterfaces
The implemented interfaces.
-
classAnnotations
private AnnotationInfoList classAnnotations
The class annotations.
-
fullyQualifiedDefiningMethodName
private java.lang.String fullyQualifiedDefiningMethodName
The fully qualified name of the defining method.
-
classContainmentEntries
private java.util.List<Classfile.ClassContainment> classContainmentEntries
Class containment entries.
-
annotationParamDefaultValues
private AnnotationParameterValueList annotationParamDefaultValues
Annotation default parameter values.
-
refdClassNames
private java.util.Set<java.lang.String> refdClassNames
Referenced class names.
-
fieldInfoList
private FieldInfoList fieldInfoList
The field info list.
-
methodInfoList
private MethodInfoList methodInfoList
The method info list.
-
typeSignatureStr
private java.lang.String typeSignatureStr
The type signature.
-
sourceFile
private java.lang.String sourceFile
The source file, such as Classfile.java
-
classTypeAnnotationDecorators
private java.util.List<Classfile.ClassTypeAnnotationDecorator> classTypeAnnotationDecorators
The type annotation decorators for theClassTypeSignatureinstance.
-
acceptedClassNamesFound
private final java.util.Set<java.lang.String> acceptedClassNamesFound
The names of accepted classes found in the classpath while scanning paths within classpath elements.
-
classNamesScheduledForExtendedScanning
private final java.util.Set<java.lang.String> classNamesScheduledForExtendedScanning
The names of external (non-accepted) classes scheduled for extended scanning (where scanning is extended upwards to superclasses, interfaces and annotations).
-
additionalWorkUnits
private java.util.List<Scanner.ClassfileScanWorkUnit> additionalWorkUnits
Any additional work units scheduled for scanning.
-
scanSpec
private final ScanSpec scanSpec
The scan spec.
-
cpCount
private int cpCount
The number of constant pool entries plus one.
-
entryOffset
private int[] entryOffset
The byte offset for the beginning of each entry in the constant pool.
-
entryTag
private int[] entryTag
The tag (type) for each entry in the constant pool.
-
indirectStringRefs
private int[] indirectStringRefs
The indirection index for String/Class entries in the constant pool.
-
NO_ANNOTATIONS
private static final AnnotationInfo[] NO_ANNOTATIONS
An empty array for the case where there are no annotations.
-
-
Constructor Detail
-
Classfile
Classfile(ClasspathElement classpathElement, java.util.List<ClasspathElement> classpathOrder, java.util.Set<java.lang.String> acceptedClassNamesFound, java.util.Set<java.lang.String> classNamesScheduledForExtendedScanning, java.lang.String relativePath, Resource classfileResource, boolean isExternalClass, java.util.concurrent.ConcurrentHashMap<java.lang.String,java.lang.String> stringInternMap, WorkQueue<Scanner.ClassfileScanWorkUnit> workQueue, ScanSpec scanSpec, LogNode log) throws java.io.IOException, Classfile.ClassfileFormatException, Classfile.SkipClassException
Directly 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:
java.io.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 Detail
-
scheduleScanningIfExternalClass
private void scheduleScanningIfExternalClass(java.lang.String className, java.lang.String relationship, LogNode log)Extend scanning to a superclass, interface or annotation.- Parameters:
className- the class namerelationship- the relationship typelog- the log
-
extendScanningUpwardsFromAnnotationParameterValues
private void extendScanningUpwardsFromAnnotationParameterValues(java.lang.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
private void extendScanningUpwards(LogNode log)
Check if scanning needs to be extended upwards to an external superclass, interface or annotation.- Parameters:
log- the log
-
link
void link(java.util.Map<java.lang.String,ClassInfo> classNameToClassInfo, java.util.Map<java.lang.String,PackageInfo> packageNameToPackageInfo, java.util.Map<java.lang.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
private java.lang.String intern(java.lang.String str)
Intern a string.- Parameters:
str- the str- Returns:
- the string
-
getConstantPoolStringOffset
private int getConstantPoolStringOffset(int cpIdx, int subFieldIdx) throws Classfile.ClassfileFormatExceptionGet 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 java.lang.String getConstantPoolString(int cpIdx, boolean replaceSlashWithDot, boolean stripLSemicolon) throws Classfile.ClassfileFormatException, java.io.IOExceptionGet 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.java.io.IOException- If an IO exception occurs.
-
getConstantPoolString
private java.lang.String getConstantPoolString(int cpIdx, int subFieldIdx) throws Classfile.ClassfileFormatException, java.io.IOExceptionGet 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.java.io.IOException- If an IO exception occurs.
-
getConstantPoolString
private java.lang.String getConstantPoolString(int cpIdx) throws Classfile.ClassfileFormatException, java.io.IOExceptionGet a string from the constant pool.- Parameters:
cpIdx- the constant pool index- Returns:
- the constant pool string
- Throws:
Classfile.ClassfileFormatException- If a problem occurs.java.io.IOException- If an IO exception occurs.
-
getConstantPoolStringFirstByte
private byte getConstantPoolStringFirstByte(int cpIdx) throws Classfile.ClassfileFormatException, java.io.IOExceptionGet 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.java.io.IOException- If an IO exception occurs.
-
getConstantPoolClassName
private java.lang.String getConstantPoolClassName(int cpIdx) throws Classfile.ClassfileFormatException, java.io.IOExceptionGet 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.java.io.IOException- If an IO exception occurs.
-
getConstantPoolClassDescriptor
private java.lang.String getConstantPoolClassDescriptor(int cpIdx) throws Classfile.ClassfileFormatException, java.io.IOExceptionGet 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.java.io.IOException- If an IO exception occurs.
-
constantPoolStringEquals
private boolean constantPoolStringEquals(int cpIdx, java.lang.String asciiStr) throws Classfile.ClassfileFormatException, java.io.IOExceptionCompare 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.java.io.IOException- If an IO exception occurs.
-
cpReadInt
private int cpReadInt(int cpIdx) throws java.io.IOExceptionRead an int from the constant pool.- Parameters:
cpIdx- the constant pool index.- Returns:
- the int
- Throws:
java.io.IOException- If an I/O exception occurred.
-
cpReadLong
private long cpReadLong(int cpIdx) throws java.io.IOExceptionRead a long from the constant pool.- Parameters:
cpIdx- the constant pool index.- Returns:
- the long
- Throws:
java.io.IOException- If an I/O exception occurred.
-
getFieldConstantPoolValue
private java.lang.Object getFieldConstantPoolValue(int tag, char fieldTypeDescriptorFirstChar, int cpIdx) throws Classfile.ClassfileFormatException, java.io.IOExceptionGet 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.java.io.IOException- If an IO exception occurs.
-
readAnnotation
private AnnotationInfo readAnnotation() throws java.io.IOException
Read annotation entry from classfile.- Returns:
- the annotation, as an
AnnotationInfoobject. - Throws:
java.io.IOException- If an IO exception occurs.
-
readAnnotationElementValue
private java.lang.Object readAnnotationElementValue() throws java.io.IOExceptionRead annotation element value from classfile.- Returns:
- the annotation element value
- Throws:
java.io.IOException- If an IO exception occurs.
-
readTypePath
private java.util.List<Classfile.TypePathNode> readTypePath() throws java.io.IOException
- Throws:
java.io.IOException
-
readConstantPoolEntries
private void readConstantPoolEntries(LogNode log) throws java.io.IOException
Read constant pool entries.- Parameters:
log- The log- Throws:
java.io.IOException- Signals that an I/O exception has occurred.
-
readBasicClassInfo
private void readBasicClassInfo() throws java.io.IOException, Classfile.ClassfileFormatException, Classfile.SkipClassExceptionRead basic class information.- Throws:
java.io.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
private void readInterfaces() throws java.io.IOExceptionRead the class' interfaces.- Throws:
java.io.IOException- if an I/O exception occurs.
-
readFields
private void readFields() throws java.io.IOException, Classfile.ClassfileFormatExceptionRead the class' fields.- Throws:
java.io.IOException- if an I/O exception occurs.Classfile.ClassfileFormatException- if the classfile is incorrectly formatted.
-
readMethods
private void readMethods() throws java.io.IOException, Classfile.ClassfileFormatExceptionRead the class' methods.- Throws:
java.io.IOException- if an I/O exception occurs.Classfile.ClassfileFormatException- if the classfile is incorrectly formatted.
-
readClassAttributes
private void readClassAttributes() throws java.io.IOException, Classfile.ClassfileFormatExceptionRead class attributes.- Throws:
java.io.IOException- if an I/O exception occurs.Classfile.ClassfileFormatException- if the classfile is incorrectly formatted.
-
-