Reputation: 1051
While migrating a Spring Boot application from Spring Boot 1.4.0 to Spring Boot 2, I started getting errors on trying to read a property from my .properties file.
In the properties file, the property is defined as:
environment=dev
And in one of my classes, I am importing the property through the @Value
annotation, like this:
@Getter
@Setter
public class CustomUserFilter extends SwitchUserFilter {
...
@Value("${environment}")
private String environment;
...
The class above overrides org.springframework.security.web.authentication.switchuser.SwitchUserFilter
, to enable users to switch roles.
Until Spring Boot 1.4.0, I was able to import this property in my class as a String. However, ever 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 happening. I also tried changing the type of this variable to Environment (org.springframework.core.env.Environment)
(as 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 as to what could be wrong? I am using Spring Boot 2.0, Spring 5, Java 11, and Tomcat 8.5.35. Thanks!
Upvotes: 3
Views: 1834
Reputation: 1051
The problem was unrelated to 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 an attribute private Environment environment;
. Further, this class was modified in Spring 5 release to include a getter method on this attribute. Spring 5 introduced a getEnvironment()
with return type Environment
in class GenericFilterBean
, which was conflicting with my getEnvironment()
with return type String
.
To avoid this conflict, I simply changed the name of my attribute from environment
to env
and things worked after that.
Upvotes: 3