@ -144,6 +144,9 @@ import org.springframework.util.StringUtils;
@@ -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;
@@ -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;
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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