I have an application using spring boot 2.5.1 (I have tried 2.4.8 and 2.5.2 with the same result), packaged as war file, deployed to tomcat 9.

If I have a file (instead of a directory) named "config" in the working directory of the tomcat server, I get the following Exception:

java.lang.IllegalStateException: Unable to load config data resource from pattern 'file:./config/*/application.yaml'
        at org.springframework.boot.context.config.LocationResourceLoader.getDirectory(LocationResourceLoader.java:141)
        at org.springframework.boot.context.config.LocationResourceLoader.getResources(LocationResourceLoader.java:102)
        at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolvePattern(StandardConfigDataLocationResolver.java:312)
        at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:298)
        at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:252)
        at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:119)
        at org.springframework.boot.context.config.ConfigDataLocationResolvers.lambda$resolve$1(ConfigDataLocationResolvers.java:116)
        at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:127)
        at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:116)
        at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:107)
        at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:107)
        at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:99)
        at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:86)
        at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:122)
        at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:240)
        at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:227)
        at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102)
        at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94)
        at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:100)
        at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:86)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82)
        at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:63)
        at java.util.ArrayList.forEach(ArrayList.java:1249)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:62)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:374)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:332)
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175)
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155)
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5098)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:742)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:718)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:703)
        at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:630)
        at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1840)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
        at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:525)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:424)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1585)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:308)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
        at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424)
        at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367)
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:966)
        at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1427)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1417)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:943)
        at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:258)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:682)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: java.lang.IllegalStateException: 'config' is not a directory
        at org.springframework.util.Assert.state(Assert.java:97)
        at org.springframework.boot.context.config.LocationResourceLoader.getDirectory(LocationResourceLoader.java:137)
        ... 75 more

Apparently the file "config" is picket up during the search for spring boot configuration files, but then the assertion fails.

Comment From: eugenelesnov

Hi, friends! I wanted to get involved and did a little research on this issue.

At first glance, it's all about StandardConfigDataLocationResolver#isDirectory check. We define is this file or directory only if the path ends with a separator or /.

Naive solution is to add something like this:

private boolean isDirectory(String resourceLocation) {
       return Files.isDirectory(Path.of(resourceLocation)) 
        || (resourceLocation.endsWith("/") || resourceLocation.endsWith(File.separator));
}

The problem is at higher level of abstraction in StandardConfigDataLocationResolver#getReferences. Because when we determine that the file config is not a directory, we try to process it as a file with predefined file extensions. And meh - we have IllegalStateException with message File extension is not known to any PropertySourceLoader

How do I have process this situation at all?

P.S. English is not my native language :)

Comment From: eugenelesnov

My guess is we don't need to process this file at all..

Comment From: mbhave

Hi @EugeneLesnov, thanks for offering to help but this issue is already assigned and I am looking into it. You can look at the issue tracker for other issues that do not have anyone assigned to them. You can comment on the one you'd like to work on so that we're aware you'll be working on it.

Comment From: eugenelesnov

@mbhave There were no comments..OK, thanks for responding Have a nice day :)

Comment From: snicoll

@EugeneLesnov we don't necessarily add a comment but you can see if the issue is assigned or not on this page.