-
-
Notifications
You must be signed in to change notification settings - Fork 298
Resource API
See also the ClassGraph API overview.
💡 If you just need the content of the resource as a String, call Resource#getContentAsString().
A Resource can be opened as a ByteBuffer, InputStream or loaded as a byte[] array. For ByteBuffer and InputStream, be sure to call .close() on the Resource once you have finished with it:
ResourceList matchingResources = scanResult.getResourcesWithPath("config/cfg.xml");
for (Resource resource : matchingResources) {
try {
InputStream inputStream = resource.open();
// ... Use inputStream ...
} finally {
resource.close();
}
}The above is equivalent to the following pattern (putting Resource resToClose = resource; as the first entry in the try header will cause resource to be closed after inputStream is closed):
ResourceList matchingResources = scanResult.getResourcesWithPath("config/cfg.xml");
for (Resource resource : matchingResources) {
try (Resource resToClose = resource; InputStream inputStream = resource.open()) {
// ... Use inputStream ...
}
}Alternatively you can use the ResourceList#forEach*() methods, which call Resource#close() for you:
ResourceList matchingResources = scanResult.getResourcesWithPath("config/cfg.xml");
matchingResources.forEachInputStreamIgnoringIOException((resource, inputStream) -> {
// ... Use inputStream ...
});
A reference to a file found within a classath directory or jarfile, or within a module. Obtained by calling ScanResult#getAllResources() and related methods.
In addition to optionally scanning classes on the classpath, ClassGraph always records the names of all resources (files) encountered in accepted packages during the scan (including classfiles and non-class files). The content of any resource file, or resource files with paths matching a certain pattern, can be read after the scan.
Behind the scenes, ClassGraph tries to open resources as memory-mapped file channel wherever possible for speed, while transparently translating from the fastest available API for accessing any given resource to whichever API mechanism you want to use to read the resource, allowing you to access the resource as either an InputStream, ByteBuffer or byte[] array, in the fastest way possible.
-
Reading resource content:
💡 The best way to read from resources is by filtering a
ResourceListfor resources with paths of interest, then calling.forEachByteArrayIgnoringIOException(ByteArrayConsumer),.forEachByteArrayThrowingIOException(ByteArrayConsumerThrowsIOException),.forEachInputStreamIgnoringIOException(InputStreamConsumer),.forEachInputStreamThrowingIOException(InputStreamConsumerThrowsIOException),.forEachByteBufferIgnoringIOException(InputStreamConsumer)or.forEachByteBufferThrowingIOException(InputStreamConsumerTrowsIOException), since these all properly close theResourceafter the consumer has read from the resource.💡 However, if you want to read the contents of a
Resourcemanually, using one of the following methods, don't forget to callResource#close()when you have finished reading from the resource.💡 ClassGraph will transparently translate the mechanism for accessing the underlying resource type (whether the resource is a file in a directory, or an entry in a jarfile, or a resource in a module) to
ByteBuffer,InputStreamorbyte[]array, in the most efficient manner possible.🛑 Important:
Resourceis not threadsafe -- you should only have any givenResourceopen in one thread at a time.-
.open()opens the resource as anInputStream. -
.read()opens the resource as aByteBuffer. Note that you must call.close()on theResourcewhen you are finished with thisByteBufferto release theByteBuffer. Alternatively, callResource#readCloseable()instead (see below). -
.readCloseable()returns aCloseableByteBufferthat implements theCloseableinterface, so that when itsclose()method is called, it automatically callsResource#close()to release the wrappedByteBuffer. CallCloseableByteBuffer#getByteBuffer()to get the wrappedByteBuffer. -
.load()loads the entire content of the resource as abyte[]array. (This calls.close()on theResourceonce all content is loaded.) - **
.getContentAsString()**is a convenience method that calls.load()to get the resource content, then defines and returnsString. (Assumes UTF8 encoding.) -
.close()closes the underlyingInputStreamor releases/unmaps the underlyingByteBufferfor theResource.
-
-
Reading resource metadata:
-
.getLength()returns the length of the resource in bytes, or-1if unknown. The value generally remains unknown until.read()or.load()is called. If you call.open(), the length of the resultingInputStreammay or may not be known. -
getPosixPermissions()returns the POSIX file permissions for theResourceas aSet<PosixFilePermission>, obtained from either the directory entry for the containing directory (for dir-based resources), or the zipfile central directory (for jarfile resources). If not available or unknown (e.g. for system module resources or jlink'd resources), returns null. -
getLastModified()returns the last modified timestamp for the resource (in milliseconds since the epoch), if known. If not available or unknown (e.g. for system module resources or jlink'd resources), returns0L. -
.getPath()returns the path of the resource, relative to the package root, as aString. For example, for a resource path ofBOOT-INF/classes/com/xyz/resource.xmland a package root ofBOOT-INF/classes/, returnscom/xyz/resource.xml. -
.getPathRelativeToClasspathElement()returns the path of the resource relative to the classpath element (instead of relative to the package root) as aString. For example, for a resource path ofBOOT-INF/classes/com/xyz/resource.xml, returnsBOOT-INF/classes/com/xyz/resource.xml, even if the package root isBOOT-INF/classes/. -
.getURI()returns aURIfor the resource. -
.getURL()returns aURLfor the resource. Note that this will throwIllegalArgumentExceptionif the resource was obtained from a system module or a jlink'd runtime image, since the URI scheme ofjrt:is only supported byURI, not byURL. -
.getClasspathElementURI()returns aURIfor the classpath element containing the resource. -
.getClasspathElementURL()returns aURLfor the classpath element containing the resource. Note that this will throwIllegalArgumentExceptionif the resource was obtained from a system module or a jlink'd runtime image, since the URI scheme ofjrt:is only supported byURI, not byURL. -
.getClasspathElementFile()returns aFilefor the classpath element containing the resource, or null if the resource was contained in a system module or jlinkd runtime image (since the.getClasspathElementURI()will return aURIwithjrt:` scheme, which cannot be resolved to a file). -
.getModuleRef()returns aModuleReffor the module containing the resource, or null if the resource was contained in a directory or jarfile on the traditional classpath.
-
Extends ArrayList<Resource> with the following convenience methods:
-
Converting to
Map:-
.asMap()returns theResourceListas aMap<String, ResourceList>that maps paths to aResourceListof resources that have each path.💡 If the resource path is duplicated across different classpath elements, the
ResourceListin the map values will contain more than one element. See also.findDuplicatePaths().
-
-
Reading resource metadata for each
Resourcein the list:-
.getPaths()returns a list of the paths of resources in this list relative to the package root, by calling.getPath()for eachResourcein the list. Returns aList<String>. -
.getPathsRelativeToClasspathElement()returns a list of the paths of resources in this list relative to the classpath element (instead of relative to the package root) by calling.getPathRelativeToClasspathElement()for eachResourcein the list. Returns aList<String>. -
.getURLs()returns a list of the URLs of resources in this list, as aList<URL>. You should probably use.getURIs()instead, since resource URIs can containjrt:/schemes if the resource is in a jlink'd image or a system module, andURLdoes not support this scheme. -
.getURIs()returns a list of the URIs of resources in this list, as aList<URI>. -
.getAsStrings()returns a list of the result of calling.toString()on eachResourceobject in this list, producing aList<string>ofStringrepresentations of eachResourcelocation.
-
-
Filtering
Resourceelements:-
.filter(ResourceFilter filter)returns aResourceListthat is a subset of the original list, obtained by applying the given filter predicate to eachResourcein the list.-
ResourceFilteris aFunctionalInterfacewith the single abstract methodboolean accept(Resource resource).
-
-
.classFilesOnly()returns aResourceListthat is the subset of the original list whoseResourcepaths end with ".class". -
.nonClassFilesOnly()returns aResourceListthat is the subset of the original list whoseResourcepaths do not end with ".class".
-
- Finding resources with duplicate paths:
-
Reading content of each
Resourcein the list: (these methods all have unique names to avoid running into problems of ambiguous overloaded method resolution when lambdas are used rather than classes for theconsumerparameter):💡 ClassGraph will transparently translate the mechanism for accessing the underlying resource type (whether the resource is a file in a directory, or an entry in a jarfile, or a resource in a module) to
ByteBuffer,InputStreamorbyte[]array, in the most efficient manner possible.-
.forEachByteArrayIgnoringIOException(ByteArrayConsumer consumer)loads the complete content of each resource in the list, calls theByteArrayConsumerwith the content, then callsResource#close()to clean up resources. AnyIOExceptionthrown while trying to open or read a resource causes the resource to be skipped.-
ByteArrayConsumeris aFunctionalInterfacewith the single abstract methodvoid accept(Resource resource, byte[] byteArray)
-
-
.forEachByteArrayThrowingIOException(ByteArrayConsumerThrowsIOException consumer)loads the complete content of each resource in the list, calls theByteArrayConsumerwith the content, then callsResource#close()to clean up resources. AnyIOExceptionthrown while trying to open or read a resource causes the exception to be thrown to the caller.-
ByteArrayConsumerThrowsIOExceptionis aFunctionalInterfacewith the single abstract methodvoid accept(Resource resource, byte[] byteArray) throws IOException
-
-
.forEachInputStreamIgnoringIOException(InputStreamConsumer consumer)opens each resource in the list as anInputStream, calls theInputStreamConsumerwith the content, then callsResource#close()to close theInputStream. AnyIOExceptionthrown while trying to open or read a resource causes the resource to be skipped.-
InputStreamConsumeris aFunctionalInterfacewith the single abstract methodvoid accept(Resource resource, InputStream inputStream)
-
-
.forEachInputStreamThrowingingIOException(InputStreamConsumerThrowsIOException consumer)opens each resource in the list as anInputStream, calls theInputStreamConsumerwith the content, then callsResource#close()to close theInputStream. AnyIOExceptionthrown while trying to open or read a resource causes the resource to be thrown to the caller.-
InputStreamConsumerThrowsIOExceptionis aFunctionalInterfacewith the single abstract methodvoid accept(Resource resource, InputStream inputStream) throws IOException
-
-
.forEachByteBufferIgnoringIOException(InputStreamConsumer consumer)opens each resource in the list as aByteBuffer(memory-mapped if possible), calls theByteBufferConsumerwith the content, then callsResource#close()to release theByteBuffer. AnyIOExceptionthrown while trying to open or read a resource causes the resource to be skipped.-
ByteBufferConsumeris aFunctionalInterfacewith the single abstract methodvoid accept(Resource resource, ByteBuffer byteBuffer)
-
-
.forEachByteBufferThrowingIOException(InputStreamConsumerThrowsIOException consumer)opens each resource in the list as aByteBuffer(memory-mapped if possible), calls theByteBufferConsumerwith the content, then callsResource#close()to release theByteBuffer. AnyIOExceptionthrown while trying to open or read a resource causes the resource to be thrown to the caller.-
ByteBufferConsumerThrowsIOExceptionis aFunctionalInterfacewith the single abstract methodvoid accept(Resource resource, ByteBuffer byteBuffer) throws IOException
-
-