版本
Flowable 6.7.2
Mysql-connector-java 8.0.27
现象
Mysql驱动升级到8.0.27时,SpringBoot启动项目报了如下错误:
org.flowable.common.engine.api.FlowableException: Error initialising eventregistry data model
...
Caused by: java.lang.ClassCastException: class java.time.LocalDateTime cannot be cast to class java.lang.String (java.time.LocalDateTime and java.lang.String are in module java.base of loader ‘bootstrap’)
at liquibase.changelog.StandardChangeLogHistoryService.getRanChangeSets(StandardChangeLogHistoryService.java:328)
原因
Flowable 6.7.2 默认依赖liquibase-core:3.8.9。
liquibase通过查询数据库表变更日志检查是否需要更新表结构,由于数据库驱动版本较新,返回的数据日期格式为LocalDateTime,导致不兼容报错。
liquibase.changelog.StandardChangeLogHistoryService
public List<RanChangeSet> getRanChangeSets() throws DatabaseException {
...
// 此处tmpDateExecuted 为LocalDateTime导致报错
Object tmpDateExecuted = rs.get("DATEEXECUTED");
Date dateExecuted = null;
if (tmpDateExecuted instanceof Date) {
dateExecuted = (Date)tmpDateExecuted;
} else {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
dateExecuted = df.parse((String)tmpDateExecuted);
} catch (ParseException var24) {
}
}
...
}
解决
方案1:mysql数据库驱动版本退回到8.0.22(注意:8.0.22版本有漏洞存在,故做升级)
方案2:liquibase-core依赖版本升级到4.8.0以后的版本修复此问题
liquibase.changelog.StandardChangeLogHistoryService
public List<RanChangeSet> getRanChangeSets() throws DatabaseException {
...
Object tmpDateExecuted = rs.get("DATEEXECUTED");
Date dateExecuted = null;
if (tmpDateExecuted instanceof Date) {
dateExecuted = (Date)tmpDateExecuted;
} else if (tmpDateExecuted instanceof LocalDateTime) { // 增加了对LocalDateTime类型的处理
dateExecuted = Date.from(((LocalDateTime)tmpDateExecuted).atZone(ZoneId.systemDefault()).toInstant());
} else {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
dateExecuted = df.parse((String)tmpDateExecuted);
} catch (ParseException var26) {
}
}
...
}
到此,重新启动项目可以正常起来了。