Skip to content

ConversionService is inconsistently used in Spring Boot application #6222

Closed
@stevenschlansker

Description

@stevenschlansker

I apologize in advance for cross-posting, but I have not received useful help on Stack Overflow and I suspect that the issue I am facing is either a bug in Spring Boot or at least very poor documentation. Original context here:

http://stackoverflow.com/questions/37952166/spring-boot-test-case-doesnt-use-custom-conversion-service

Short version is, I would like to configure my ConversionService to understand new types (i.e. java.time.Duration). Per the docs, I try to wire it up with:

@Configuration
public class ConversionServiceConfiguration {
    private static final FormattingConversionService SERVICE = new DefaultFormattingConversionService();

    static {
        new DateTimeFormatterRegistrar().registerFormatters(SERVICE);
    }

    @Bean
    public static ConversionService conversionService() {
        return SERVICE;
    }
}

but it keeps being ineffective:

>  Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'AttachClientRule': Unsatisfied dependency expressed through constructor parameter 0:
> Error creating bean with name 'MyServiceConfig': Unsatisfied dependency expressed through field 'maxWatchTime': Failed to convert value of type [java.lang.String] to required type [java.time.Duration];
> nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.time.Duration]: no matching editors or conversion strategy found;

The BeanFactory still has a DefaultConversionService sticking around from before I set my own.

I can fix this one with one hack:

... implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.setConversionService(SERVICE);
    }
}

and then I get a different problem, where again the Environment doesn't have it set either!

> Caused by: java.lang.IllegalArgumentException: Cannot convert value [PT15s] from source type [String] to target type [Duration]
>   at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:94)
>   at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:65)
>   at org.springframework.core.env.AbstractPropertyResolver.getProperty(AbstractPropertyResolver.java:143)
>   at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:546)

Time for another hack:

... implements EnvironmentAware {
    @Override
    public void setEnvironment(Environment environment) {
        ((AbstractEnvironment) environment).setConversionService(SERVICE);
    }
}

And that fixes this problem.

But how long until I find the next place one of these icky DefaultConversionService instances is lying around? How can I make Spring Boot actually use my custom one for everything without having to keep diving deep into the guts and find lingering problems?

Spring 4.3.0, Spring Boot 1.4.0M3

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions