Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check exception cause for @PropertySource(ignoreResourceNotFound) support #22276

Closed
crazyk2 opened this issue Jan 17, 2019 · 8 comments
Closed
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@crazyk2
Copy link

crazyk2 commented Jan 17, 2019

<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.

@rstoyanchev rstoyanchev added status: waiting-for-triage An issue we've not yet triaged or decided on in: core Issues in core modules (aop, beans, core, context, expression) labels Jan 17, 2019
@roxanadel
Copy link

Any news on this?

@sumedhsakdeo
Copy link

sumedhsakdeo commented Feb 7, 2022

Hitting this issue as well. Any updates?
What is the workaround, catching exception in createPropertySource() is not helping.

@purple52
Copy link

purple52 commented Aug 30, 2022

In case it helps anyone, I am working around this in two parts:

  1. Use a YamlPropertiesFactoryBean to create the property source with the resolution method set to OVERRIDE_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);
    }
  1. Add a separate @PropertySource annotations for each file (the above did not work if I listed the potential file locations in a single annotation).

@urld
Copy link

urld commented Dec 12, 2022

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;
         }
      }

@sbrannen sbrannen changed the title ignoreResourceNotFound=true in @PropertySource doesn't work with PropertySourceFactory which uses YamlPropertySourceLoader @PropertySource(ignoreResourceNotFound=true) fails with PropertySourceFactory which uses YamlPropertySourceLoader Aug 2, 2023
@sbrannen sbrannen changed the title @PropertySource(ignoreResourceNotFound=true) fails with PropertySourceFactory which uses YamlPropertySourceLoader ignoreResourceNotFound flag in @PropertySource is ignored if PropertySourceFactory throws IllegalStateException Aug 2, 2023
@sbrannen
Copy link
Member

sbrannen commented Aug 2, 2023

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.

@sbrannen
Copy link
Member

sbrannen commented Aug 3, 2023

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.

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.

@sbrannen
Copy link
Member

sbrannen commented Aug 3, 2023

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.

@sbrannen sbrannen added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Aug 3, 2023
@sbrannen sbrannen self-assigned this Aug 3, 2023
@sbrannen sbrannen added this to the 6.0.12 milestone Aug 3, 2023
@sbrannen sbrannen changed the title ignoreResourceNotFound flag in @PropertySource is ignored if PropertySourceFactory throws IllegalStateException Support ignoreResourceNotFound flag in @PropertySource if PropertySourceFactory throws IllegalStateException Aug 5, 2023
@sbrannen sbrannen changed the title Support ignoreResourceNotFound flag in @PropertySource if PropertySourceFactory throws IllegalStateException Check exception cause for @PropertySource(ignoreResourceNotFound) support Aug 5, 2023
@sbrannen sbrannen changed the title Check exception cause for @PropertySource(ignoreResourceNotFound) support Check exception cause for @PropertySource(ignoreResourceNotFound) support Aug 5, 2023
@sbrannen
Copy link
Member

sbrannen commented Aug 5, 2023

This has been addressed in 4a81814 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

7 participants