You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Krzysztof Jamróz (Jira)" <ji...@apache.org> on 2021/01/29 11:00:00 UTC
[jira] [Created] (CAMEL-16111) Bean reference by name in properties
not working when there are custom property converters
Krzysztof Jamróz created CAMEL-16111:
----------------------------------------
Summary: 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
Affects Versions: 3.7.1
Reporter: Krzysztof Jamróz
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)