|
Hi Costin,
This issue still exists. Consider the following code from a Spring managed component which implements ResourceLoaderAware: String path = "classpath*:META-INF/resource-1.xml"; String result = "From ResourceLoader's InputStream via '" + path + "':\n"; if (this.resourceLoader instanceof ResourcePatternResolver) { ResourcePatternResolver resourcePatternResolver = (ResourcePatternResolver) this.resourceLoader; Resource[] resources = resourcePatternResolver.getResources(path); for (Resource resource : resources) { InputStream inputStream = null; try { inputStream = resource.getInputStream(); result += FileCopyUtils.copyToString(new BufferedReader(new InputStreamReader(inputStream))); result += "\n"; } finally { if (inputStream != null) { inputStream.close(); } } } } In my test case, Bundle-Classpath = .,MODULE-INF, and the root of the bundle does in fact contain the file META-INF/resource-1.xml. As I mentioned before, this fails on the call to resourcePatternResolver.getResources(path) as follows: java.io.FileNotFoundException: OSGi resource[MODULE-INF/META-INF/resource-1.xml|bnd.id=85|bnd.sym=web_module_resource_loading-1.0.0.BUILD-20080725124936-web_module_resource_loading.web] cannot be resolved to URL because it does not exist at org.springframework.osgi.io.OsgiBundleResource.getURL(OsgiBundleResource.java:224) at org.springframework.osgi.io.OsgiBundleResourcePatternResolver.findBundleClassPathMatchingFolders(OsgiBundleResourcePatternResolver.java:461) Note that if I remove MODULE-INF from the bundle classpath, the code executes as expected and properly locates the classpath*:META-INF/resource-1.xml resource. Thanks for looking into this! Sam I've found the problem and committed a fix. The problem aren't invalid bundle classpath entries but missing resources in these entries (which trigger an exception when doing a search for classpath*:).
Hi Costin,
I've not yet run any code against your fix, but based on visual inspection, I can't imagine that the current code solves the problem I initially reported. Specifically, the for-loop remains unchanged. So it appears that you have only solved the issue when the returned list of candidate resources is of length one. When the returned list of candidate resources is greater than one, however, the chance that one of the candidate resources does not exist still remains. Thus, the only robust solution I can envision is one similar to what I laid out in the description of this issue: // untested code: for (int i = 0; i < resources.length; i++) { Resource resource = resources[i]; if (resource.exists()) { list.add(resource.getURL().getPath()); } } Please take another look at this issue. Sam, please test the code and if you run into the problem again let me know. I appreciate the 'visual inspection' but there are integration tests in place that show things are running fine as they are : the resources returned by the resource loader always exist (they are tested during discovery, after all since this is a pattern based matching, it's hard to find/detect resources that do not exist) - the case with the array of fixed length takes care case where no resources are found.
Costin, you are indeed correct: you only have to call resource.exists() if the size of the candidate resource array is larger than one.
I guess I just wasn't "imaginative" enough with my visual inspection. ;) Our tests pass, and as a result I'll re-close this issue. Thanks, Sam Changes have been successfully tested.
|
||||||||||||||||||||||||||||||||||||||||||||||
I've tried your example and with logging on, the invalid entries are filtered out early. Here is a snippet:
main TRACE [io.OsgiBundleResourcePatternResolver] - Analyzing Bundle-ClassPath entries for bundle [20|org.springframework.osgi.iandt.io.functional.fragments]
main TRACE [io.OsgiBundleResourcePatternResolver] - Found Bundle-ClassPath entries {., bundleclasspath/folder, bundleclasspath/simple.jar, foo}
main TRACE [io.OsgiBundleResourcePatternResolver] - Classpath entry [bundleclasspath/folder] resolves to [bundleentry://20/bundleclasspath/folder/]
main TRACE [io.OsgiBundleResourcePatternResolver] - Resolved location pattern [bundleclasspath/folder/*.file] to resources []
main TRACE [io.OsgiBundleResourcePatternResolver] - Classpath entry [bundleclasspath/simple.jar] resolves to [bundleentry://20/bundleclasspath/simple.jar]
main TRACE [io.OsgiBundleResourcePatternResolver] - Classpath entry [foo] resolves to [null]
Notice that since foo resolves to null, any search for it will be discarded.
Do you have a stracktrace for this bug?