shardingsphere-elasticjob
shardingsphere-elasticjob copied to clipboard
DataSourceConfiguration.createDataSource,invoke setter method,When the setter method is overloaded and the parameter type is not String, throw java.lang.IllegalArgumentException: argument type mismatch
Bug Report
Please answer these questions before submitting your issue. Thanks!
Which version of ElasticJob did you use?:ElasticJob-Lite3.0.2,Spring Boot v2.3.4,druid1.2.8
Which project did you use? ElasticJob-Lite or ElasticJob-Cloud?:ElasticJob-Lite
Expected behavior:Application run success
Actual behavior : ERROR org.springframework.boot.SpringApplication : Application run failed
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_301]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_301]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_301]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_301]
at org.apache.shardingsphere.elasticjob.tracing.rdb.datasource.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:121) ~[elasticjob-tracing-rdb-3.0.2.jar:3.0.2]
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_301]
at org.apache.shardingsphere.elasticjob.tracing.rdb.datasource.DataSourceRegistry.getDataSource(DataSourceRegistry.java:65) ~[elasticjob-tracing-rdb-3.0.2.jar:3.0.2]
at org.apache.shardingsphere.elasticjob.tracing.rdb.datasource.DataSourceConfiguration.getStorage(DataSourceConfiguration.java:102) ~[elasticjob-tracing-rdb-3.0.2.jar:3.0.2]
at org.apache.shardingsphere.elasticjob.tracing.rdb.datasource.DataSourceConfiguration.getStorage(DataSourceConfiguration.java:43) ~[elasticjob-tracing-rdb-3.0.2.jar:3.0.2]
at org.apache.shardingsphere.elasticjob.tracing.listener.TracingListenerFactory.getListener(TracingListenerFactory.java:56) ~[elasticjob-tracing-api-3.0.2.jar:3.0.2]
at org.apache.shardingsphere.elasticjob.tracing.JobTracingEventBus.register(JobTracingEventBus.java:69) ~[elasticjob-tracing-api-3.0.2.jar:3.0.2]
at org.apache.shardingsphere.elasticjob.tracing.JobTracingEventBus.
Reason analyze (If you can)
When the setter method is overloaded,findSetterMethod,Only the method name and only one parameter are judged. If there is a method overload and the parameter type is not String, an argument type mismatch exception will be thrown,It is necessary to judge that the parameter type of the setter method is String
Steps to reproduce the behavior.
Example codes for reproduce this issue (such as a github link).
private Optional<Method> findSetterMethod(final Method[] methods, final String property) {
String setterMethodName = Joiner.on("").join(SETTER_PREFIX, CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, property));
for (Method each : methods) {
if (each.getName().equals(setterMethodName) && 1 == each.getParameterTypes().length) {
return Optional.of(each);
}
}
return Optional.empty();
}
@SneakyThrows(ReflectiveOperationException.class)
public DataSource createDataSource() {
DataSource result = (DataSource) Class.forName(dataSourceClassName).getConstructor().newInstance();
Method[] methods = result.getClass().getMethods();
for (Entry<String, Object> entry : props.entrySet()) {
if (SKIPPED_PROPERTY_NAMES.contains(entry.getKey())) {
continue;
}
Optional<Method> setterMethod = findSetterMethod(methods, entry.getKey());
if (setterMethod.isPresent()) {
setterMethod.get().invoke(result, entry.getValue());
}
}
Optional<JDBCParameterDecorator> decorator = findJDBCParameterDecorator(result);
return decorator.isPresent() ? decorator.get().decorate(result) : result;
}
Thanks for your feedback. Using reflection is not a good way to construct a DataSource. This should be refactored.