You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2021/02/01 12:52:01 UTC

[jira] [Assigned] (CAMEL-16111) camel-spring-boot - Bean reference by name in properties not working when there are custom property converters

     [ https://issues.apache.org/jira/browse/CAMEL-16111?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen reassigned CAMEL-16111:
-----------------------------------

    Assignee: Claus Ibsen

> camel-spring-boot - Bean reference by name in properties not working when there are custom property converters
> --------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-16111
>                 URL: https://issues.apache.org/jira/browse/CAMEL-16111
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-spring-boot-starters
>    Affects Versions: 3.7.1
>            Reporter: Krzysztof Jamróz
>            Assignee: Claus Ibsen
>            Priority: Minor
>         Attachments: CamelSpringBootCannotConvertQuartzProperty.zip
>
>
> Bean reference by name ({{#bean:name syntax}}) in properties not working when there are custom converters registered in Spring Boot Application. I use Spring Boot 2.4.2 and Camel 3.7.1 to create Quartz component with manally defined scheduler via property:
> {{camel.component.quartz.scheduler=#quartzScheduler}}
> This causes error:
> {quote}Failed to bind properties under 'camel.component.quartz.scheduler' to org.quartz.Scheduler:
> Property: camel.component.quartz.scheduler
>  Value: #quartzScheduler
>  Origin: class path resource [application.properties] - 93:34
>  Reason: No converter found capable of converting from type [java.lang.String] to type[org.quartz.Scheduler]
> {quote}
> Previously, in Spring Boot 2.3.0 and Camel 3.3.0 it worked ok.
>  Debugging shows that problem is caused by the fact that:
>  * {{QuartzComponentConverter}} registers itself only in {{ApplicationConversionService.getSharedInstance}}
>  * {{QuartzComponentConverter}} is _not_ a bean in Spring context
>  * {{org.springframework.boot.context.properties.ConversionServiceDeducer.Factory.create()}} creates separate instance of {{ApplicationConversionService}} if there are any custom converters (which indeed are present in application configuration)
> Quick workaround is to add custom property converter similar to {{QuartzComponentConverter}} that will be picked by the {{ConversionServiceDeducer}}:
> {code:java}
> @ConfigurationPropertiesBinding
> @Component
> public class QuartzComponentPropertyConverter implements GenericConverter {
>     @Autowired
>     private ApplicationContext applicationContext;
>     public Set<ConvertiblePair> getConvertibleTypes() {
>         Set<ConvertiblePair> answer = new LinkedHashSet<>();
>         answer.add(new ConvertiblePair(String.class, org.quartz.Scheduler.class));
>         answer.add(new ConvertiblePair(String.class, org.quartz.SchedulerFactory.class));
>         return answer;
>     }
>     public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
>         if (source == null) {
>             return null;
>         }
>         String ref = source.toString();
>         if (!ref.startsWith("#")) {
>             return null;
>         }
>         ref = ref.startsWith("#bean:") ? ref.substring(6) : ref.substring(1);
>         switch (targetType.getName()) {
>         case "org.quartz.Scheduler":
>             return applicationContext.getBean(ref, org.quartz.Scheduler.class);
>         case "org.quartz.SchedulerFactory":
>             return applicationContext.getBean(ref, org.quartz.SchedulerFactory.class);
>         }
>         return null;
>     }
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)