The existing answers that propose using ClassLoader.getResources(String)
only work if the "name" in question is the full path of the resource. As the methods's javadoc states, "The name of a resource is a /
-separated path name that identifies the resource." It's unfortunate and misleading that the parameter is called "name" instead of "path."
For those who, like me, are really looking for all resources with a given (simple) name - without knowing the full path of the resource - the current answers won't work. @NandkumarTekale's code example states "resources will contain all java files and sub-packages" in the comments, but unfortunately that is not true. Nor does it make any difference to use ClassLoader.findResources(String)
(which is indeed protected in the ClassLoader
class itself, but pulled into the public API by concrete subclasses like URLClassLoader
, which in turn serves as the base class for most commonly used class loaders).
The most straightforward solution that I could find uses the ClassGraph library:
try (ScanResult result = new ClassGraph().acceptClasspathElementsContainingResourcePath("*/html5.dtd").scan())
{
System.err.println(result.getResourcesWithLeafName("html5.dtd").getURLs());
}
Sadly, this clashes with the OP's request for a solution without the use of third-party libraries. However, ClassGraph's source code is available on GitHub and can be used as an inspiration for a "home grown" solution. In broad strokes, one would have to find the class loader's base URLs (e.g., using URLClassLoader.getURLs()
) and then write URL-specific code for searching the contents of each URL (e.g., if it's a jar:file:
... URL, load the JAR and iterate over its contents, or if it's a file:
... URL use java.io.File
to explore the folder contents). There are a lot of special cases to consider, though (e.g., OSGi class loaders), and a truly general solution would probably replicate a fair amount of what ClassGraph does under the hood. If it is valid to assume that the resources will, for example, always be packaged in a JAR (or always as plain files in the file system), a more tailored solution could be created for just those cases.