提交 08748eca 编写于 作者: J Juergen Hoeller

PathMatchingResourcePatternResolver evaluates classpath manifest entries as well

Issue: SPR-13685
上级 2cfe00ce
......@@ -144,6 +144,9 @@ import org.springframework.util.StringUtils;
* root of expanded directories. This originates from a limitation in the JDK's
* {@code ClassLoader.getResources()} method which only returns file system
* locations for a passed-in empty String (indicating potential roots to search).
* This {@code ResourcePatternResolver} implementation is trying to mitigate the
* jar root lookup limitation through {@link URLClassLoader} introspection and
* "java.class.path" manifest evaluation; however, without portability guarantees.
*
* <p><b>WARNING:</b> Ant-style patterns with "classpath:" resources are not
* guaranteed to find matching resources if the root package to search is available
......@@ -156,9 +159,9 @@ import org.springframework.util.StringUtils;
* classpath:com/mycompany/**&#47;service-context.xml
* </pre>
* is used to try to resolve it, the resolver will work off the (first) URL
* returned by {@code getResource("com/mycompany");}. If this base package
* node exists in multiple classloader locations, the actual end resource may
* not be underneath. Therefore, preferably, use "{@code classpath*:}" with the same
* returned by {@code getResource("com/mycompany");}. If this base package node
* exists in multiple classloader locations, the actual end resource may not be
* underneath. Therefore, preferably, use "{@code classpath*:}" with the same
* Ant-style pattern in such a case, which will search <i>all</i> class path
* locations that contain the root package.
*
......@@ -166,6 +169,7 @@ import org.springframework.util.StringUtils;
* @author Colin Sampaleanu
* @author Marius Bogoevici
* @author Costin Leau
* @author Phil Webb
* @since 1.0.2
* @see #CLASSPATH_ALL_URL_PREFIX
* @see org.springframework.util.AntPathMatcher
......@@ -316,6 +320,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
* Called by {@link #findAllClassPathResources(String)}.
* @param path the absolute path within the classpath (never a leading slash)
* @return a mutable Set of matching Resource instances
* @since 4.1.1
*/
protected Set<Resource> doFindAllClassPathResources(String path) throws IOException {
Set<Resource> result = new LinkedHashSet<Resource>(16);
......@@ -350,6 +355,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
* given set of resources in the form of pointers to the root of the jar file content.
* @param classLoader the ClassLoader to search (including its ancestors)
* @param result the set of resources to add jar roots to
* @since 4.1.1
*/
protected void addAllClassLoaderJarRoots(ClassLoader classLoader, Set<Resource> result) {
if (classLoader instanceof URLClassLoader) {
......@@ -379,8 +385,15 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
}
}
}
if (classLoader == ClassLoader.getSystemClassLoader()) {
// "java.class.path" manifest evaluation...
addClassPathManifestEntries(result);
}
if (classLoader != null) {
try {
// Hierarchy traversal...
addAllClassLoaderJarRoots(classLoader.getParent(), result);
}
catch (Exception ex) {
......@@ -392,6 +405,41 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
}
}
/**
* Determine jar file references from the "java.class.path." manifest property and add them
* to the given set of resources in the form of pointers to the root of the jar file content.
* @param result the set of resources to add jar roots to
* @since 4.3
*/
protected void addClassPathManifestEntries(Set<Resource> result) {
try {
String javaClassPathProperty = System.getProperty("java.class.path");
for (String url : StringUtils.delimitedListToStringArray(
javaClassPathProperty, System.getProperty("path.separator"))) {
try {
if (url.endsWith(ResourceUtils.JAR_FILE_EXTENSION)) {
UrlResource jarResource = new UrlResource(ResourceUtils.JAR_URL_PREFIX +
ResourceUtils.FILE_URL_PREFIX + url + ResourceUtils.JAR_URL_SEPARATOR);
if (jarResource.exists()) {
result.add(jarResource);
}
}
}
catch (MalformedURLException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Cannot search for matching files underneath [" + url +
"] because it cannot be converted to a valid 'jar:' URL: " + ex.getMessage());
}
}
}
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to evaluate 'java.class.path' manifest entries: " + ex);
}
}
}
/**
* Find all resources that match the given location pattern via the
* Ant-style PathMatcher. Supports resources in jar files and zip files
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册