Package io.github.classgraph
Class Classfile
- java.lang.Object
-
- io.github.classgraph.Classfile
-
class Classfile extends java.lang.Object
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 Classes Modifier and Type Class Description (package private) static class
Classfile.ClassContainment
Class containment.(package private) static class
Classfile.ClassfileFormatException
Thrown when a classfile's contents are not in the correct format.(package private) static interface
Classfile.ClassTypeAnnotationDecorator
(package private) static interface
Classfile.MethodTypeAnnotationDecorator
(package private) static class
Classfile.SkipClassException
Thrown when a classfile needs to be skipped.(package private) static interface
Classfile.TypeAnnotationDecorator
(package private) static class
Classfile.TypePathNode
-
Field Summary
Fields Modifier and Type Field Description private java.util.Set<java.lang.String>
acceptedClassNamesFound
The names of accepted classes found in the classpath while scanning paths within classpath elements.private java.util.List<Scanner.ClassfileScanWorkUnit>
additionalWorkUnits
Any additional work units scheduled for scanning.private AnnotationParameterValueList
annotationParamDefaultValues
Annotation default parameter values.private AnnotationInfoList
classAnnotations
The class annotations.private java.util.List<Classfile.ClassContainment>
classContainmentEntries
Class containment entries.private Resource
classfileResource
The classfile resource.private int
classModifiers
The class modifiers.private java.lang.String
className
The name of the class.private 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).private ClasspathElement
classpathElement
The classpath element that contains this classfile.private java.util.List<ClasspathElement>
classpathOrder
The classpath order.private java.util.List<Classfile.ClassTypeAnnotationDecorator>
classTypeAnnotationDecorators
The type annotation decorators for theClassTypeSignature
instance.private int
cpCount
The number of constant pool entries plus one.private int[]
entryOffset
The byte offset for the beginning of each entry in the constant pool.private int[]
entryTag
The tag (type) for each entry in the constant pool.private FieldInfoList
fieldInfoList
The field info list.private java.lang.String
fullyQualifiedDefiningMethodName
The fully qualified name of the defining method.private java.util.List<java.lang.String>
implementedInterfaces
The implemented interfaces.private int[]
indirectStringRefs
The indirection index for String/Class entries in the constant pool.private boolean
isAnnotation
Whether this class is an annotation.private boolean
isExternalClass
Whether this is an external class.private boolean
isInterface
Whether this class is an interface.private boolean
isRecord
Whether this class is a record.private int
majorVersion
The major version of the classfile format.private MethodInfoList
methodInfoList
The method info list.private int
minorVersion
The minor version of the classfile format.private static AnnotationInfo[]
NO_ANNOTATIONS
An empty array for the case where there are no annotations.private ClassfileReader
reader
TheClassfileReader
for the current classfile.private java.util.Set<java.lang.String>
refdClassNames
Referenced class names.private java.lang.String
relativePath
The relative path to the classfile (should correspond to className).private ScanSpec
scanSpec
The scan spec.private java.lang.String
sourceFile
The source file, such as Classfile.javaprivate java.util.concurrent.ConcurrentHashMap<java.lang.String,java.lang.String>
stringInternMap
The string intern map.private java.lang.String
superclassName
The superclass name.private java.lang.String
typeSignatureStr
The 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 boolean
constantPoolStringEquals(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 int
cpReadInt(int cpIdx)
Read an int from the constant pool.private long
cpReadLong(int cpIdx)
Read a long from the constant pool.private void
extendScanningUpwards(LogNode log)
Check if scanning needs to be extended upwards to an external superclass, interface or annotation.private void
extendScanningUpwardsFromAnnotationParameterValues(java.lang.Object annotationParamVal, LogNode log)
Check if scanning needs to be extended upwards from an annotation parameter value.private java.lang.String
getConstantPoolClassDescriptor(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.String
getConstantPoolClassName(int cpIdx)
Get a string from the constant pool, and interpret it as a class name by replacing '/' with '.'.private java.lang.String
getConstantPoolString(int cpIdx)
Get a string from the constant pool.private java.lang.String
getConstantPoolString(int cpIdx, boolean replaceSlashWithDot, boolean stripLSemicolon)
Get a string from the constant pool, optionally replacing '/' with '.'.private java.lang.String
getConstantPoolString(int cpIdx, int subFieldIdx)
Get a string from the constant pool.private byte
getConstantPoolStringFirstByte(int cpIdx)
Get the first UTF8 byte of a string in the constant pool, or '\0' if the string is null or empty.private int
getConstantPoolStringOffset(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.Object
getFieldConstantPoolValue(int tag, char fieldTypeDescriptorFirstChar, int cpIdx)
Get a field constant from the constant pool.private java.lang.String
intern(java.lang.String str)
Intern a string.(package private) 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.private AnnotationInfo
readAnnotation()
Read annotation entry from classfile.private java.lang.Object
readAnnotationElementValue()
Read annotation element value from classfile.private void
readBasicClassInfo()
Read basic class information.private void
readClassAttributes()
Read class attributes.private void
readConstantPoolEntries(LogNode log)
Read constant pool entries.private void
readFields()
Read the class' fields.private void
readInterfaces()
Read the class' interfaces.private void
readMethods()
Read the class' methods.private java.util.List<Classfile.TypePathNode>
readTypePath()
private void
scheduleScanningIfExternalClass(java.lang.String className, java.lang.String relationship, LogNode log)
Extend scanning to a superclass, interface or annotation.
-
-
-
Field Detail
-
reader
private ClassfileReader reader
TheClassfileReader
for 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 theClassTypeSignature
instance.
-
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
- theAnnotationInfo
object 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.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 java.lang.String getConstantPoolString(int cpIdx, boolean replaceSlashWithDot, boolean stripLSemicolon) throws Classfile.ClassfileFormatException, java.io.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.java.io.IOException
- If an IO exception occurs.
-
getConstantPoolString
private java.lang.String getConstantPoolString(int cpIdx, int subFieldIdx) throws Classfile.ClassfileFormatException, java.io.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.java.io.IOException
- If an IO exception occurs.
-
getConstantPoolString
private java.lang.String getConstantPoolString(int cpIdx) throws Classfile.ClassfileFormatException, java.io.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.java.io.IOException
- If an IO exception occurs.
-
getConstantPoolStringFirstByte
private byte getConstantPoolStringFirstByte(int cpIdx) throws Classfile.ClassfileFormatException, java.io.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.java.io.IOException
- If an IO exception occurs.
-
getConstantPoolClassName
private java.lang.String getConstantPoolClassName(int cpIdx) throws Classfile.ClassfileFormatException, java.io.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.java.io.IOException
- If an IO exception occurs.
-
getConstantPoolClassDescriptor
private java.lang.String getConstantPoolClassDescriptor(int cpIdx) throws Classfile.ClassfileFormatException, java.io.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.java.io.IOException
- If an IO exception occurs.
-
constantPoolStringEquals
private boolean constantPoolStringEquals(int cpIdx, java.lang.String asciiStr) throws Classfile.ClassfileFormatException, java.io.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.java.io.IOException
- If an IO exception occurs.
-
cpReadInt
private int cpReadInt(int cpIdx) throws java.io.IOException
Read 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.IOException
Read 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.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.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
AnnotationInfo
object. - Throws:
java.io.IOException
- If an IO exception occurs.
-
readAnnotationElementValue
private java.lang.Object readAnnotationElementValue() throws java.io.IOException
Read 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.SkipClassException
Read 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.IOException
Read the class' interfaces.- Throws:
java.io.IOException
- if an I/O exception occurs.
-
readFields
private void readFields() throws java.io.IOException, Classfile.ClassfileFormatException
Read 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.ClassfileFormatException
Read 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.ClassfileFormatException
Read class attributes.- Throws:
java.io.IOException
- if an I/O exception occurs.Classfile.ClassfileFormatException
- if the classfile is incorrectly formatted.
-
-