diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/config/SortedResourcesFactoryBean.java b/spring-jdbc/src/main/java/org/springframework/jdbc/config/SortedResourcesFactoryBean.java index 77776adf446..51ea9aaad72 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/config/SortedResourcesFactoryBean.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/config/SortedResourcesFactoryBean.java @@ -72,20 +72,22 @@ public class SortedResourcesFactoryBean extends AbstractFactoryBean @Override protected Resource[] createInstance() throws Exception { - List scripts = new ArrayList<>(); + List result = new ArrayList<>(); for (String location : this.locations) { Resource[] resources = this.resourcePatternResolver.getResources(location); // Cache URLs to avoid repeated I/O during sorting Map urlCache = new LinkedHashMap<>(resources.length); + List failingResources = new ArrayList<>(); for (Resource resource : resources) { try { urlCache.put(resource, resource.getURL().toString()); } catch (IOException ex) { - throw new IllegalStateException( - "Failed to resolve URL for resource [" + resource + - "] from location pattern [" + location + "]", ex); + if (logger.isDebugEnabled()) { + logger.debug("Failed to resolve " + resource + " for sorting purposes: " + ex); + } + failingResources.add(resource); } } @@ -93,9 +95,10 @@ public class SortedResourcesFactoryBean extends AbstractFactoryBean List sortedResources = new ArrayList<>(urlCache.keySet()); sortedResources.sort(Comparator.comparing(urlCache::get)); - scripts.addAll(sortedResources); + result.addAll(sortedResources); + result.addAll(failingResources); } - return scripts.toArray(new Resource[0]); + return result.toArray(new Resource[0]); } } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java index 342b9a467d3..b6a15deca17 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java @@ -22,6 +22,7 @@ import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; @@ -33,6 +34,7 @@ import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean; +import org.springframework.jdbc.datasource.init.CannotReadScriptException; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import static org.assertj.core.api.Assertions.assertThat; @@ -67,6 +69,13 @@ class JdbcNamespaceIntegrationTests { assertCorrectSetup("jdbc-config-pattern.xml", "dataSource"); } + @Test + void createWithNonExistentResource() { + assertThatExceptionOfType(BeanCreationException.class) + .isThrownBy(() -> assertCorrectSetup("jdbc-config-nonexistent.xml", "dataSource")) + .withCauseInstanceOf(CannotReadScriptException.class); + } + @Test void createWithAnonymousDataSourceAndDefaultDatabaseName() { assertThat(extractDataSourceUrl("jdbc-config-db-name-default-and-anonymous-datasource.xml")) diff --git a/spring-jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-config-nonexistent.xml b/spring-jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-config-nonexistent.xml new file mode 100644 index 00000000000..c8314f0ce5f --- /dev/null +++ b/spring-jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-config-nonexistent.xml @@ -0,0 +1,14 @@ + + + + + + + + + +