Spring Boot 2.5.0.

https://github.com/spring-projects/spring-boot/blob/7b490f003c4830a2981d20310dfbb64910a971f5/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolver.java#L97

There is something incorrect in above line logic, because if one tries to get Integer property from PropertySource, it first goes to above class and then proxies the request to DefaultResolver but without placeholder resolution, and if you have property defined as:

some_property=${SOME_ENV_VAR:100} the default resolver fails with ConversionFailedException.

Probable resolution:

  1. use true for resolveNestedPlaceholders in above line, but that will call placeholder resolution and type conversion twice.
  2. use getPropertyAsRawString in below line: https://github.com/spring-projects/spring-boot/blob/7b490f003c4830a2981d20310dfbb64910a971f5/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolver.java#L123

Example

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    static class DummyBean {

    }

    @Bean
    DummyBean dummy(Environment env) {
        env.getProperty("some_property");                // Works
        env.getProperty("some_property", Integer.class); // Fails
        return new DummyBean();
    }

}

Properties

some_property=${VAR:1000}

Stacktrace

Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value '${VAR:1000}'; nested exception is java.lang.NumberFormatException: For input string: "${VAR:1000}"
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.env.AbstractPropertyResolver.convertValueIfNecessary(AbstractPropertyResolver.java:265) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:91) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver$DefaultResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:123) ~[spring-boot-2.5.0.jar:2.5.0]
    at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.findPropertyValue(ConfigurationPropertySourcesPropertyResolver.java:97) ~[spring-boot-2.5.0.jar:2.5.0]
    at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:74) ~[spring-boot-2.5.0.jar:2.5.0]
    at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:65) ~[spring-boot-2.5.0.jar:2.5.0]
    at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:599) ~[spring-core-5.3.7.jar:5.3.7]
    at com.example.demo.DemoApplication.dummy(DemoApplication.java:22) ~[classes/:na]
    at com.example.demo.DemoApplication$$EnhancerBySpringCGLIB$$7d44c475.CGLIB$dummy$0(<generated>) ~[classes/:na]
    at com.example.demo.DemoApplication$$EnhancerBySpringCGLIB$$7d44c475$$FastClassBySpringCGLIB$$cf8dcca2.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.7.jar:5.3.7]
    at com.example.demo.DemoApplication$$EnhancerBySpringCGLIB$$7d44c475.dummy(<generated>) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.7.jar:5.3.7]
    ... 19 common frames omitted
Caused by: java.lang.NumberFormatException: For input string: "${VAR:1000}"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:na]
    at java.base/java.lang.Integer.parseInt(Integer.java:638) ~[na:na]
    at java.base/java.lang.Integer.valueOf(Integer.java:983) ~[na:na]
    at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:211) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:64) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:50) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:437) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.3.7.jar:5.3.7]
    ... 39 common frames omitted

Comment From: philwebb

Thanks for the detailed report. I've pushed an update that will hopefully fix this in the next release.