Skip to content

Commit ccff526

Browse files
committed
Reintroduce logging and exception handling for file system resource scanning
See gh-29163
1 parent 7cb54de commit ccff526

File tree

1 file changed

+71
-34
lines changed

1 file changed

+71
-34
lines changed

spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java

+71-34
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@
3434
import java.nio.file.FileSystem;
3535
import java.nio.file.FileSystems;
3636
import java.nio.file.Files;
37-
import java.nio.file.NoSuchFileException;
3837
import java.nio.file.Path;
3938
import java.util.Collections;
4039
import java.util.Enumeration;
41-
import java.util.HashSet;
4240
import java.util.LinkedHashSet;
4341
import java.util.Map;
4442
import java.util.Objects;
@@ -738,49 +736,88 @@ protected JarFile getJarFile(String jarFileUrl) throws IOException {
738736
protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern)
739737
throws IOException {
740738

741-
URI rootDirUri = rootDirResource.getURI();
742-
String rootDir = rootDirUri.getPath();
743-
// If the URI is for a "resource" in the GraalVM native image file system, we have to
744-
// ensure that the root directory does not end in a slash while simultaneously ensuring
745-
// that the root directory is not an empty string (since fileSystem.getPath("").resolve(str)
746-
// throws an ArrayIndexOutOfBoundsException in a native image).
747-
if ("resource".equals(rootDirUri.getScheme()) && (rootDir.length() > 1) && rootDir.endsWith("/")) {
748-
rootDir = rootDir.substring(0, rootDir.length() - 1);
749-
}
750-
751-
FileSystem fileSystem;
739+
URI rootDirUri;
740+
String rootDir;
752741
try {
753-
fileSystem = FileSystems.getFileSystem(rootDirUri.resolve("/"));
742+
rootDirUri = rootDirResource.getURI();
743+
rootDir = rootDirUri.getPath();
744+
// If the URI is for a "resource" in the GraalVM native image file system, we have to
745+
// ensure that the root directory does not end in a slash while simultaneously ensuring
746+
// that the root directory is not an empty string (since fileSystem.getPath("").resolve(str)
747+
// throws an ArrayIndexOutOfBoundsException in a native image).
748+
if ("resource".equals(rootDirUri.getScheme()) && (rootDir.length() > 1) && rootDir.endsWith("/")) {
749+
rootDir = rootDir.substring(0, rootDir.length() - 1);
750+
}
754751
}
755752
catch (Exception ex) {
756-
fileSystem = FileSystems.newFileSystem(rootDirUri.resolve("/"), Map.of(),
757-
ClassUtils.getDefaultClassLoader());
753+
if (logger.isInfoEnabled()) {
754+
logger.info("Failed to resolve %s in the file system: %s".formatted(rootDirResource, ex));
755+
}
756+
return Collections.emptySet();
758757
}
759758

760-
Path rootPath = fileSystem.getPath(rootDir);
761-
String resourcePattern = rootPath.resolve(subPattern).toString();
762-
Predicate<Path> resourcePatternMatches = path -> getPathMatcher().match(resourcePattern, path.toString());
763-
Set<Resource> result = new HashSet<>();
764-
try (Stream<Path> files = Files.walk(rootPath)) {
765-
files.filter(resourcePatternMatches).sorted().forEach(file -> {
766-
try {
767-
result.add(convertToResource(file.toUri()));
768-
}
769-
catch (Exception ex) {
770-
// TODO Introduce logging
759+
FileSystem fileSystem = getFileSystem(rootDirUri);
760+
if (fileSystem == null) {
761+
return Collections.emptySet();
762+
}
763+
764+
try {
765+
Path rootPath = fileSystem.getPath(rootDir);
766+
String resourcePattern = rootPath.resolve(subPattern).toString();
767+
Predicate<Path> resourcePatternMatches = path -> getPathMatcher().match(resourcePattern, path.toString());
768+
if (logger.isTraceEnabled()) {
769+
logger.trace("Searching directory [%s] for files matching pattern [%s]"
770+
.formatted(rootPath.toAbsolutePath(), subPattern));
771+
}
772+
Set<Resource> result = new LinkedHashSet<>();
773+
try (Stream<Path> files = Files.walk(rootPath)) {
774+
files.filter(resourcePatternMatches).sorted().forEach(file -> {
775+
try {
776+
result.add(convertToResource(file.toUri()));
777+
}
778+
catch (Exception ex) {
779+
if (logger.isDebugEnabled()) {
780+
logger.debug("Failed to convert file %s to an org.springframework.core.io.Resource: %s"
781+
.formatted(file, ex));
782+
}
783+
}
784+
});
785+
}
786+
catch (Exception ex) {
787+
if (logger.isDebugEnabled()) {
788+
logger.debug("Faild to complete search in directory [%s] for files matching pattern [%s]: %s"
789+
.formatted(rootPath.toAbsolutePath(), subPattern, ex));
771790
}
772-
});
791+
}
792+
return result;
773793
}
774-
catch (NoSuchFileException ex) {
775-
// TODO Introduce logging
794+
finally {
795+
try {
796+
fileSystem.close();
797+
}
798+
catch (UnsupportedOperationException ex) {
799+
// ignore
800+
}
776801
}
802+
}
803+
804+
@Nullable
805+
private FileSystem getFileSystem(URI uri) {
777806
try {
778-
fileSystem.close();
807+
URI root = uri.resolve("/");
808+
try {
809+
return FileSystems.getFileSystem(root);
810+
}
811+
catch (Exception ex) {
812+
return FileSystems.newFileSystem(root, Map.of(), ClassUtils.getDefaultClassLoader());
813+
}
779814
}
780-
catch (UnsupportedOperationException ex) {
781-
// TODO Introduce logging
815+
catch (Exception ex) {
816+
if (logger.isInfoEnabled()) {
817+
logger.info("Failed to resolve java.nio.file.FileSystem for %s: %s".formatted(uri, ex));
818+
}
819+
return null;
782820
}
783-
return result;
784821
}
785822

786823
/**

0 commit comments

Comments
 (0)