I'm using Spring-Boot 3.2.5 on a project that has properties-files stored in sub-directories:
$ find src/main/resources/config/ -type f
src/main/resources/config/phot/application.properties
src/main/resources/config/soc/application.properties
src/main/resources/config/distr/application.properties
src/main/resources/config/mgmt/application.properties
$
In my main application.properties I have this:
spring.config.import=classpath:config/*/
When I run the application from my IDE it works fine. Building the project with Maven results in a JAR containing the properties-files:
$ unzip -l target/mediadistr.jar | grep properties
0 2024-05-18 17:03 BOOT-INF/classes/com/mediadistr/config/properties/
1275 2024-05-18 17:03 BOOT-INF/classes/config/phot/application.properties
55 2024-05-18 17:03 BOOT-INF/classes/config/soc/application.properties
47 2024-05-18 17:03 BOOT-INF/classes/config/distr/application.properties
4320 2024-05-18 17:03 BOOT-INF/classes/config/mgmt/application.properties
1509 2024-05-18 17:03 BOOT-INF/classes/application.properties
64 2024-05-18 17:03 META-INF/maven/com.mediadistr/mediadistr/pom.properties
However, when running the JAR I get this exception:
17:44:02.299 [main] ERROR org.springframework.boot.SpringApplication -- Application run failed
java.lang.IllegalStateException: Unable to load config data resource from pattern 'classpath:/config/*/application.yaml'
at org.springframework.boot.context.config.LocationResourceLoader.getFile(LocationResourceLoader.java:142)
at org.springframework.boot.context.config.LocationResourceLoader.getResources(LocationResourceLoader.java:102)
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolvePattern(StandardConfigDataLocationResolver.java:317)
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:303)
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:254)
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:121)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.lambda$resolve$1(ConfigDataLocationResolvers.java:102)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:113)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:102)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:94)
at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:106)
at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:98)
at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:86)
at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:115)
at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:242)
at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:229)
at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:96)
at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:89)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:109)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:94)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:369)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:329)
at com.mediadistr.Application.main(Application.java:32)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58)
Caused by: java.io.FileNotFoundException: class path resource [config/] cannot be resolved to absolute file path because it does not reside in the file system: jar:nested:/home/vermgit/coding/source/java/projects/com.mediadistr/target/mediadistr.jar/!BOOT-INF/classes/!/config/
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:218)
at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:173)
at org.springframework.boot.context.config.LocationResourceLoader.getFile(LocationResourceLoader.java:139)
... 40 common frames omitted
The resource path seems wrong: jar:nested:/home/vermgit/coding/source/java/projects/com.mediadistr/target/mediadistr.jar/!BOOT-INF/classes/!/config/
The last "/!" shouldn't be there, it should rather be "/classes/config/" at the end.
Note that this configuration also doesn't work:
spring.config.import=classpath:config/*/application.properties
However, this works:
spring.config.import=classpath:config/phot/application.properties,\
classpath:config/soc/application.properties,\
classpath:config/distr/application.properties,\
classpath:config/mgmt/application.properties
Comment From: wilkinsona
This is to be expected. Wildcard support was introduced for wildcard config tree imports that are filesystem-based. That is works at all with classpath: resources is down to luck rather than intention. As described in the documentation wildcards are only intended for use with external directories.