@@ -235,9 +235,6 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
235
235
private static final Predicate <ResolvedModule > isNotSystemModule =
236
236
resolvedModule -> !systemModuleNames .contains (resolvedModule .name ());
237
237
238
- @ Nullable
239
- private static Set <ClassPathManifestEntry > classPathManifestEntriesCache ;
240
-
241
238
@ Nullable
242
239
private static Method equinoxResolveMethod ;
243
240
@@ -261,7 +258,10 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
261
258
262
259
private final Map <String , Resource []> rootDirCache = new ConcurrentHashMap <>();
263
260
264
- private final Map <String , NavigableSet <String >> jarEntryCache = new ConcurrentHashMap <>();
261
+ private final Map <String , NavigableSet <String >> jarEntriesCache = new ConcurrentHashMap <>();
262
+
263
+ @ Nullable
264
+ private volatile Set <ClassPathManifestEntry > manifestEntriesCache ;
265
265
266
266
267
267
/**
@@ -377,7 +377,8 @@ public Resource[] getResources(String locationPattern) throws IOException {
377
377
*/
378
378
public void clearCache () {
379
379
this .rootDirCache .clear ();
380
- this .jarEntryCache .clear ();
380
+ this .jarEntriesCache .clear ();
381
+ this .manifestEntriesCache = null ;
381
382
}
382
383
383
384
@@ -530,10 +531,10 @@ protected void addAllClassLoaderJarRoots(@Nullable ClassLoader classLoader, Set<
530
531
* @since 4.3
531
532
*/
532
533
protected void addClassPathManifestEntries (Set <Resource > result ) {
533
- Set <ClassPathManifestEntry > entries = classPathManifestEntriesCache ;
534
+ Set <ClassPathManifestEntry > entries = this . manifestEntriesCache ;
534
535
if (entries == null ) {
535
536
entries = getClassPathManifestEntries ();
536
- classPathManifestEntriesCache = entries ;
537
+ this . manifestEntriesCache = entries ;
537
538
}
538
539
for (ClassPathManifestEntry entry : entries ) {
539
540
if (!result .contains (entry .resource ()) &&
@@ -544,7 +545,7 @@ protected void addClassPathManifestEntries(Set<Resource> result) {
544
545
}
545
546
546
547
private Set <ClassPathManifestEntry > getClassPathManifestEntries () {
547
- Set <ClassPathManifestEntry > manifestEntries = new HashSet <>();
548
+ Set <ClassPathManifestEntry > manifestEntries = new LinkedHashSet <>();
548
549
Set <File > seen = new HashSet <>();
549
550
try {
550
551
String paths = System .getProperty ("java.class.path" );
@@ -578,9 +579,9 @@ private Set<ClassPathManifestEntry> getClassPathManifestEntriesFromJar(File jar)
578
579
File parent = jar .getAbsoluteFile ().getParentFile ();
579
580
try (JarFile jarFile = new JarFile (jar )) {
580
581
Manifest manifest = jarFile .getManifest ();
581
- Attributes attributes = (manifest != null ) ? manifest .getMainAttributes () : null ;
582
- String classPath = (attributes != null ) ? attributes .getValue (Name .CLASS_PATH ) : null ;
583
- Set <ClassPathManifestEntry > manifestEntries = new HashSet <>();
582
+ Attributes attributes = (manifest != null ? manifest .getMainAttributes () : null ) ;
583
+ String classPath = (attributes != null ? attributes .getValue (Name .CLASS_PATH ) : null ) ;
584
+ Set <ClassPathManifestEntry > manifestEntries = new LinkedHashSet <>();
584
585
if (StringUtils .hasLength (classPath )) {
585
586
StringTokenizer tokenizer = new StringTokenizer (classPath );
586
587
while (tokenizer .hasMoreTokens ()) {
@@ -806,11 +807,11 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
806
807
if (separatorIndex != -1 ) {
807
808
jarFileUrl = urlFile .substring (0 , separatorIndex );
808
809
rootEntryPath = urlFile .substring (separatorIndex + 2 ); // both separators are 2 chars
809
- NavigableSet <String > entryCache = this .jarEntryCache .get (jarFileUrl );
810
- if (entryCache != null ) {
810
+ NavigableSet <String > entriesCache = this .jarEntriesCache .get (jarFileUrl );
811
+ if (entriesCache != null ) {
811
812
Set <Resource > result = new LinkedHashSet <>(64 );
812
813
// Search sorted entries from first entry with rootEntryPath prefix
813
- for (String entryPath : entryCache .tailSet (rootEntryPath , false )) {
814
+ for (String entryPath : entriesCache .tailSet (rootEntryPath , false )) {
814
815
if (!entryPath .startsWith (rootEntryPath )) {
815
816
// We are beyond the potential matches in the current TreeSet.
816
817
break ;
@@ -870,11 +871,9 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
870
871
rootEntryPath = rootEntryPath + "/" ;
871
872
}
872
873
Set <Resource > result = new LinkedHashSet <>(64 );
873
- NavigableSet <String > entryCache = new TreeSet <>();
874
- for (Enumeration <JarEntry > entries = jarFile .entries (); entries .hasMoreElements (); ) {
875
- JarEntry entry = entries .nextElement ();
876
- String entryPath = entry .getName ();
877
- entryCache .add (entryPath );
874
+ NavigableSet <String > entriesCache = new TreeSet <>();
875
+ for (String entryPath : jarFile .stream ().map (JarEntry ::getName ).sorted ().toList ()) {
876
+ entriesCache .add (entryPath );
878
877
if (entryPath .startsWith (rootEntryPath )) {
879
878
String relativePath = entryPath .substring (rootEntryPath .length ());
880
879
if (getPathMatcher ().match (subPattern , relativePath )) {
@@ -883,7 +882,7 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
883
882
}
884
883
}
885
884
// Cache jar entries in TreeSet for efficient searching on re-encounter.
886
- this .jarEntryCache .put (jarFileUrl , entryCache );
885
+ this .jarEntriesCache .put (jarFileUrl , entriesCache );
887
886
return result ;
888
887
}
889
888
finally {
@@ -1236,9 +1235,9 @@ private static Resource createAlternative(String path) {
1236
1235
}
1237
1236
}
1238
1237
1239
- private static Resource asJarFileResource (String path )
1240
- throws MalformedURLException {
1238
+ private static Resource asJarFileResource (String path ) throws MalformedURLException {
1241
1239
return new UrlResource (JARFILE_URL_PREFIX + path + ResourceUtils .JAR_URL_SEPARATOR );
1242
1240
}
1243
1241
}
1242
+
1244
1243
}
0 commit comments