Class NestedJarHandler
java.lang.Object
nonapi.io.github.classgraph.fastzipfilereader.NestedJarHandler
Open and read jarfiles, which may be nested within other jarfiles.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static class
private static class
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate SingletonMap
<File, PhysicalZipFile, IOException> A singleton map from a zipfile'sFile
to thePhysicalZipFile
for that file, used to ensure that theRandomAccessFile
andFileChannel
for any given zipfile is opened only once.private final AtomicBoolean
True ifclose(LogNode)
has been called.private static final int
The default size of a file buffer.private SingletonMap
<FastZipEntry, ZipFileSlice, IOException> A singleton map from aFastZipEntry
to theZipFileSlice
wrapping either the zip entry data, if the entry is stored, or a ByteBuffer, if the zip entry was inflated to memory, or a physical file on disk if the zip entry was inflated to a temporary file.private static final int
HTTP(S) timeout, ms.A recycler forInflater
instances.The interruption checker.private static final int
The maximum initial buffer size.A singleton map from aModuleRef
to aModuleReaderProxy
recycler for the module.A singleton map from nested jarfile path to a tuple of the logical zipfile for the path, and the package root within the logical zipfile.FileSlice
instances that are currently open.private static Method
System.runFinalization() -- deprecated in JDK 18, so accessed by reflection.final ScanSpec
TheScanSpec
.static final String
The separator between random temp filename part and leafname.Any temporary files created while scanning.A singleton map from aZipFileSlice
to theLogicalZipFile
for that slice. -
Constructor Summary
ConstructorsConstructorDescriptionNestedJarHandler
(ScanSpec scanSpec, InterruptionChecker interruptionChecker, ReflectionUtils reflectionUtils) A handler for nested jars. -
Method Summary
Modifier and TypeMethodDescriptionvoid
Close zipfiles, modules, and recyclers, and delete temporary files.void
closeDirectByteBuffer
(ByteBuffer backingByteBuffer) private PhysicalZipFile
downloadJarFromURL
(String jarURL, LogNode log) Download a jar from a URL to a temporary file, or to a ByteBuffer if the temporary directory is not writeable or full.private static String
Get the leafname of a path.makeTempFile
(String filePathBase, boolean onlyUseLeafname) Create a temporary file, and mark it for deletion on exit.void
markSliceAsClosed
(Slice slice) Mark aSlice
as closed.void
markSliceAsOpen
(Slice slice) Mark aSlice
as open, so it can be closed when theScanResult
is closed.openInflaterInputStream
(InputStream rawInputStream) static byte[]
readAllBytesAsArray
(InputStream inputStream, long uncompressedLengthHint) Read all the bytes in anInputStream
.readAllBytesWithSpilloverToDisk
(InputStream inputStream, String tempFileBaseName, long inputStreamLengthHint, LogNode log) Read all the bytes in anInputStream
, with spillover to a temporary file on disk if a maximum buffer size is exceeded.(package private) void
removeTempFile
(File tempFile) Attempt to remove a temporary file.void
private String
sanitizeFilename
(String filename) Sanitize filename.private FileSlice
spillToDisk
(InputStream inputStream, String tempFileBaseName, byte[] buf, byte[] overflowBuf, LogNode log) Spill anInputStream
to disk if the stream is too large to fit in RAM.
-
Field Details
-
scanSpec
TheScanSpec
. -
reflectionUtils
-
canonicalFileToPhysicalZipFileMap
A singleton map from a zipfile'sFile
to thePhysicalZipFile
for that file, used to ensure that theRandomAccessFile
andFileChannel
for any given zipfile is opened only once. -
fastZipEntryToZipFileSliceMap
A singleton map from aFastZipEntry
to theZipFileSlice
wrapping either the zip entry data, if the entry is stored, or a ByteBuffer, if the zip entry was inflated to memory, or a physical file on disk if the zip entry was inflated to a temporary file. -
zipFileSliceToLogicalZipFileMap
A singleton map from aZipFileSlice
to theLogicalZipFile
for that slice. -
nestedPathToLogicalZipFileAndPackageRootMap
public SingletonMap<String,Map.Entry<LogicalZipFile, nestedPathToLogicalZipFileAndPackageRootMapString>, IOException> A singleton map from nested jarfile path to a tuple of the logical zipfile for the path, and the package root within the logical zipfile. -
moduleRefToModuleReaderProxyRecyclerMap
public SingletonMap<ModuleRef,Recycler<ModuleReaderProxy, moduleRefToModuleReaderProxyRecyclerMapIOException>, IOException> A singleton map from aModuleRef
to aModuleReaderProxy
recycler for the module. -
inflaterRecycler
A recycler forInflater
instances. -
openSlices
FileSlice
instances that are currently open. -
tempFiles
Any temporary files created while scanning. -
TEMP_FILENAME_LEAF_SEPARATOR
The separator between random temp filename part and leafname.- See Also:
-
closed
True ifclose(LogNode)
has been called. -
interruptionChecker
The interruption checker. -
DEFAULT_BUFFER_SIZE
private static final int DEFAULT_BUFFER_SIZEThe default size of a file buffer.- See Also:
-
MAX_INITIAL_BUFFER_SIZE
private static final int MAX_INITIAL_BUFFER_SIZEThe maximum initial buffer size.- See Also:
-
HTTP_TIMEOUT
private static final int HTTP_TIMEOUTHTTP(S) timeout, ms.- See Also:
-
runFinalizationMethod
System.runFinalization() -- deprecated in JDK 18, so accessed by reflection.
-
-
Constructor Details
-
NestedJarHandler
public NestedJarHandler(ScanSpec scanSpec, InterruptionChecker interruptionChecker, ReflectionUtils reflectionUtils) A handler for nested jars.- Parameters:
scanSpec
- TheScanSpec
.interruptionChecker
- the interruption checker
-
-
Method Details
-
leafname
Get the leafname of a path.- Parameters:
path
- the path- Returns:
- the string
-
sanitizeFilename
Sanitize filename.- Parameters:
filename
- the filename- Returns:
- the sanitized filename
-
makeTempFile
Create a temporary file, and mark it for deletion on exit.- Parameters:
filePathBase
- The path to derive the temporary filename from.onlyUseLeafname
- If true, only use the leafname of filePath to derive the temporary filename.- Returns:
- The temporary
File
. - Throws:
IOException
- If the temporary file could not be created.
-
removeTempFile
Attempt to remove a temporary file.- Parameters:
tempFile
- the temp file- Throws:
IOException
- If the temporary file could not be removed.SecurityException
- If the temporary file is inaccessible.
-
markSliceAsOpen
Mark aSlice
as open, so it can be closed when theScanResult
is closed.- Parameters:
slice
- theSlice
that was just opened.- Throws:
IOException
- Signals that an I/O exception has occurred.
-
markSliceAsClosed
Mark aSlice
as closed.- Parameters:
slice
- theSlice
to close.
-
downloadJarFromURL
private PhysicalZipFile downloadJarFromURL(String jarURL, LogNode log) throws IOException, InterruptedException Download a jar from a URL to a temporary file, or to a ByteBuffer if the temporary directory is not writeable or full. The downloaded jar is returned wrapped in aPhysicalZipFile
instance.- Parameters:
jarURL
- the jar URLlog
- the log- Returns:
- the temporary file or
ByteBuffer
the jar was downloaded to, wrapped in aPhysicalZipFile
instance. - Throws:
IOException
- If the jar could not be downloaded, or the jar URL is malformed.InterruptedException
- if the thread was interruptedIllegalArgumentException
- If the temp dir is not writeable, or has insufficient space to download the jar. (This is thrown as a separate exception from IOException, so that the case of an unwriteable temp dir can be handled separately, by downloading the jar to a ByteBuffer in RAM.)
-
openInflaterInputStream
- Parameters:
rawInputStream
- the raw input stream- Returns:
- the inflater input stream
- Throws:
IOException
- Signals that an I/O exception has occurred.
-
readAllBytesWithSpilloverToDisk
public Slice readAllBytesWithSpilloverToDisk(InputStream inputStream, String tempFileBaseName, long inputStreamLengthHint, LogNode log) throws IOException Read all the bytes in anInputStream
, with spillover to a temporary file on disk if a maximum buffer size is exceeded.- Parameters:
inputStream
- theInputStream
to read from.tempFileBaseName
- the source URL or zip entry that inputStream was opened from (used to name temporary file, if needed).inputStreamLengthHint
- the length of inputStream if known, else -1L.log
- the log.- Returns:
- if the
InputStream
could be read into a byte array, anArraySlice
will be returned. If this fails and theInputStream
is spilled over to disk, aFileSlice
will be returned. - Throws:
IOException
- If the contents could not be read.
-
spillToDisk
private FileSlice spillToDisk(InputStream inputStream, String tempFileBaseName, byte[] buf, byte[] overflowBuf, LogNode log) throws IOException Spill anInputStream
to disk if the stream is too large to fit in RAM.- Parameters:
inputStream
- TheInputStream
.tempFileBaseName
- The stem to base the temporary filename on.buf
- The first buffer to write to the beginning of the file, or null if none.overflowBuf
- The second buffer to write to the beginning of the file, or null if none. (Should have same nullity as buf.)log
- The log.- Returns:
- the file slice
- Throws:
IOException
- If anything went wrong creating or writing to the temp file.
-
readAllBytesAsArray
public static byte[] readAllBytesAsArray(InputStream inputStream, long uncompressedLengthHint) throws IOException Read all the bytes in anInputStream
.- Parameters:
inputStream
- TheInputStream
.uncompressedLengthHint
- The length of the data once inflated from theInputStream
, if known, otherwise -1L.- Returns:
- The contents of the
InputStream
as a byte array. - Throws:
IOException
- If the contents could not be read.
-
close
Close zipfiles, modules, and recyclers, and delete temporary files. Called byScanResult.close()
.- Parameters:
log
- The log.
-
runFinalizationMethod
public void runFinalizationMethod() -
closeDirectByteBuffer
-