Java – Spring Boot 2 cannot read properties as strings

Spring Boot 2 cannot read properties as strings… here is a solution to the problem.

Spring Boot 2 cannot read properties as strings

When migrating a Spring Boot application from Spring Boot 1.4.0 to Spring Boot 2, I started getting errors when trying to read properties from my .properties file.

In the properties file, the property is defined as:

environment=dev

In one of my classes, I import the properties via @Value annotations, as follows:

@Getter
@Setter
public class CustomUserFilter extends SwitchUserFilter {
    ...
    @Value("${environment}")
    private String environment;
    ...

The above class overrides org.springframework.security.web.authentication.switchuser.SwitchUserFilter, enabling users to switch roles.

Prior to Spring Boot 1.4.0, I was able to import this property as a string into my class. However, since migrating to Spring Boot 2, I get the following compile-time error:

Error:(43, 20) java: getEnvironment() in demo.config.CustomUserFilter
cannot implement getEnvironment() in
org.springframework.core.env.EnvironmentCapable return type
java.lang.String is not compatible with
org.springframework.core.env.Environment

I’m not sure why this is the case. I also tried changing the type of this variable to Environment (org.springframework.core.env.Environment) (shown below):

...
@Value("${environment}")
private Environment environment;
...

, but then I started getting the following error:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'switchUserFilter': Unsatisfied dependency expressed through field 'environment'; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type ' org.springframework.core.env.Environment'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment': no matching editors or conversion strategy found
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:370)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1336)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:226)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:182)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:177)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:159)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:81)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:261)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:185)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:154)
    ... 52 more
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment '; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:77)
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:60)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1089)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
    ... 70 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:117)
    at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:70)
    ... 74 more

Any clues about what might go wrong? I’m using Spring Boot 2.0, Spring 5, Java 11, and Tomcat 8.5.35. Thanks!

Solution

The problem has nothing to do with Spring Boot. My class above extends org.springframework.security.web.authentication.switchuser.SwitchUserFilter, which further extends org.springframework.web.filter.GenericFilterBean. This GenericFilterBean class also has a property, private Environment environment; 。 In addition, this class was modified in the Spring 5 release to include getter methods for this property. Spring 5 introduced getEnvironment() with a return type of Environment in the GenericFilterBean class, which is different from my getEnvironment() return type of String.

To avoid this conflict, I just changed my property name from environment to env and everything worked fine.

Related Problems and Solutions