URLClassLoader.getResources(“”) (empty resource na

2019-04-30 09:14发布

问题:

Consider a URLClassLoader parameterized with a collection of URLs which is a mix of expanded directories and jar files. For example:

URL[] urls = new URL[] {
    new URL("file:/D:/work/temp/jars/spring-security-core-3.2.0.RELEASE.jar"),
    new URL("file:/D:/work/temp/jars/spring-security-config-3.2.0.RELEASE.jar"),
    ...
    new URL("file:/D:/work/temp/domain/bin/"),
    new URL("file:/D:/work/temp/web/bin/"),
    ...
}
URLClassLoader cl = new URLClassLoader(urls);

The classloader correctly handles getResources() requests for resources located somewhere inside a package like "org/my/package/conf.properties". By correctly handles I mean the classloader successfully finds all matches inside both directories and jars.

A special empty string name passed in getResources("") is supposed to yield the URLs for all available roots (in both the directories and the jars). However there is a known limitation in ClassLoaders which results in only returning roots that correspond to directories. All roots to jars are discarded.

Using classloader.getURLs[] instead of classloader.getResources("") will not work with me as I have a complex graph of interdependent URLClassLoaders, so the results are going to be completely different. Also my classloaders are to be consumed by a third party classpath scanning facilities that uses getResources("") calls in order to set up an internal search base. This way resources located in jars are simply not found.

I currently have a working fix where I extend from URLClassLoader and manually handle requests with an empty string by forcing roots for jars in addition to those for directories within the returned collection of URLs.

However my questions are:

  • What was the conceptual/technical reason for this limitation (where paths to jars are not returned)?

  • By fixing this manually, do I violate any important contract?

  • Is there any nice way to get the desired behavior?

Thanks for any thoughts on that!