greenDao 在 qigsaw中报错Could not init DAOConfig
Posted 许佳佳233
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了greenDao 在 qigsaw中报错Could not init DAOConfig相关的知识,希望对你有一定的参考价值。
报错
org.greenrobot.greendao.DaoException: Could not init DAOConfig
场景
- 使用qigsaw
- 宿主模块依赖 greenDAO
- 插件模块使用了greenDAO
- 插件模块使用greenDAO报错:Could not init DAOConfig
原因
- greenDAO源码中通过反射的方式去调用Properties类
- 宿主模块加载greenDAO的ClassLoader是 PathClassLoader
- 插件模块加载AbstractDao实现类的ClassLoader是 QigsawClassLoader
- 由于QigsawClassLoader中没有加载DAOConfig,于是会报错。
排查方式
排查方式就是查看greenDAO源码,由于是插件化导致的崩溃,所以很快可以推断是ClassLoader的问题,验证后发现果然是。
public DaoConfig(Database db, Class<? extends AbstractDao<?, ?>> daoClass) {
this.db = db;
try {
this.tablename = (String) daoClass.getField("TABLENAME").get(null);
Property[] properties = reflectProperties(daoClass);
this.properties = properties;
allColumns = new String[properties.length];
List<String> pkColumnList = new ArrayList<String>();
List<String> nonPkColumnList = new ArrayList<String>();
Property lastPkProperty = null;
for (int i = 0; i < properties.length; i++) {
Property property = properties[i];
String name = property.columnName;
allColumns[i] = name;
if (property.primaryKey) {
pkColumnList.add(name);
lastPkProperty = property;
} else {
nonPkColumnList.add(name);
}
}
String[] nonPkColumnsArray = new String[nonPkColumnList.size()];
nonPkColumns = nonPkColumnList.toArray(nonPkColumnsArray);
String[] pkColumnsArray = new String[pkColumnList.size()];
pkColumns = pkColumnList.toArray(pkColumnsArray);
pkProperty = pkColumns.length == 1 ? lastPkProperty : null;
statements = new TableStatements(db, tablename, allColumns, pkColumns);
if (pkProperty != null) {
Class<?> type = pkProperty.type;
keyIsNumeric = type.equals(long.class) || type.equals(Long.class) || type.equals(int.class)
|| type.equals(Integer.class) || type.equals(short.class) || type.equals(Short.class)
|| type.equals(byte.class) || type.equals(Byte.class);
} else {
keyIsNumeric = false;
}
} catch (Exception e) {
throw new DaoException("Could not init DAOConfig", e);
}
}
private static Property[] reflectProperties(Class<? extends AbstractDao<?, ?>> daoClass)
throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException {
Class<?> propertiesClass = Class.forName(daoClass.getName() + "$Properties");
Field[] fields = propertiesClass.getDeclaredFields();
ArrayList<Property> propertyList = new ArrayList<Property>();
final int modifierMask = Modifier.STATIC | Modifier.PUBLIC;
for (Field field : fields) {
// There might be other fields introduced by some tools, just ignore them (see issue #28)
if ((field.getModifiers() & modifierMask) == modifierMask) {
Object fieldValue = field.get(null);
if (fieldValue instanceof Property) {
propertyList.add((Property) fieldValue);
}
}
}
Property[] properties = new Property[propertyList.size()];
for (Property property : propertyList) {
if (properties[property.ordinal] != null) {
throw new DaoException("Duplicate property ordinals");
}
properties[property.ordinal] = property;
}
return properties;
}
解决方案
解决方案还是很多的,主要还是根据业务需要来。笔者就抛砖引玉写一些可能的方案:
- 将插件中greenDAO的相关逻辑放到宿主模块中
- 如果插件中greenDAO中逻辑不多,作为临时方案,可以将greenDAO调用到的类在宿主中重复定义一遍。(只能是临时方案)
- 如宿主中没有使用greenDao的逻辑,可以改成插件直接依赖,而不要在宿主中加载。
以上是关于greenDao 在 qigsaw中报错Could not init DAOConfig的主要内容,如果未能解决你的问题,请参考以下文章
greenDao 在 qigsaw中报错Could not init DAOConfig
ThinkPHP5.0中报错could not find driver的解决方式
ssm中报错: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type a
在添加greendao 的plugin 出现?:Could not initialize class com.android.sdklib.repository.AndroidSdkHandler
Android之Fatal Exception: org.greenrobot.greendao.DaoException: Could not init DAOConfig