<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
For load properties from .yaml
I use YamlPropertySourceFactory
.
Config Example
@PropertySource(
value = ["file:\${user.dir}/1/rabbit.config.yml","file:\${user.dir}/2/rabbit.config.yml"],
factory = YamlPropertySourceFactory::class,
ignoreResourceNotFound = true)
class YamlPropertySourceFactory : PropertySourceFactory {
override fun createPropertySource(name: String?, resource: EncodedResource): PropertySource<*> {
return if (name != null)
YamlPropertySourceLoader().load(name, resource.resource).first()
else
YamlPropertySourceLoader().load(getNameForResource(resource.resource), resource.resource).first()
}
YamlPropertySourceLoader
from spring-boot-2.1.1.release leads to process function which throw IllegalStateException (in my case because FileNotFound ) but catch doesn't catch such type of exception and ignoreResourceNotFound is unreachable.
Here are two options:
A - add IllegalStateException to catch block B - change type of exception from IllegalStateException to IllegalArgumentException.
I prefer option A.
Comment From: roxanadel
Any news on this?
Comment From: sumedhsakdeo
Hitting this issue as well. Any updates? What is the workaround, catching exception in createPropertySource() is not helping.
Comment From: purple52
In case it helps anyone, I am working around this in two parts:
- Use a
YamlPropertiesFactoryBean
to create the property source with the resolution method set toOVERRIDE_AND_IGNORE
:
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
factory.setResolutionMethod(YamlProcessor.ResolutionMethod.OVERRIDE_AND_IGNORE);
Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
- Add a separate
@PropertySource
annotations for each file (the above did not work if I listed the potential file locations in a single annotation).
Comment From: urld
My workaround is to catch the exception and rethrow its cause if it fits.
So from now on, I will be living in fear of an update breaking this behavior.
try {
final YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource);
factory.afterPropertiesSet();
return factory.getObject();
} catch (final java.lang.IllegalStateException illegalState) {
if (illegalState.getCause() instanceof final FileNotFoundException e) {
// ConfigurationClassParser wants FileNotFoundException to honor PropertySource.ignoreResourceNotFound
throw e;
} else {
throw illegalState;
}
}
Comment From: sbrannen
As of Spring Framework 6.0, the issue is caused by the behavior of YamlProcessor.handleProcessError(Resource, IOException)
and PropertySourceProcessor.processPropertySource(PropertySourceDescriptor)
.
YamlProcessor.handleProcessError
converts an IOException
into an IllegalStateException
, since YamlProcessor.process(MatchCallback)
does not declare any checked exceptions.
Whereas, PropertySourceProcessor.processPropertySource
catches (IllegalArgumentException | FileNotFoundException | UnknownHostException | SocketException ex)
but not IllegalStateException
.
As mentioned by @crazyk2, one option would be to add IllegalStateException
to the catch block in PropertySourceProcessor.processPropertySource
; however, I think doing that might result in resources being ignored inappropriately.
In light of that, I am considering modifying YamlProcessor.handleProcessError
so that it rethrows an IOException
wrapped in an UncheckedIOException
and modifying PropertySourceProcessor.processPropertySource
so that it catches and unwraps an UncheckedIOException
and determines if the underlying IOException
is a FileNotFoundException
, UnknownHostException
, or SocketException
in order to appropriately ignore a missing resource.
Comment From: sbrannen
In light of that, I am considering modifying
YamlProcessor.handleProcessError
so that it rethrows anIOException
wrapped in anUncheckedIOException
and modifyingPropertySourceProcessor.processPropertySource
so that it catches and unwraps anUncheckedIOException
and determines if the underlyingIOException
is aFileNotFoundException
,UnknownHostException
, orSocketException
in order to appropriately ignore a missing resource.
Instead of switching to an UncheckedIOException
, we've decided to additionally catch RuntimeException
and check if its cause is a FileNotFoundException
, UnknownHostException
, or SocketException
to support ignoreResourceNotFound
in more use cases.
Comment From: sbrannen
My workaround is to catch the exception and rethrow its cause if it fits.
@urld, I think that's a fine workaround in the interim.
Comment From: sbrannen
This has been addressed in 4a81814dbb54b20919154b1ed92fae657deb2223 for inclusion in Spring Framework 6.0.12.
Feel free to try it out with upcoming 6.0.x snapshots, and let us know if you run into any issues.