問題
在使用 shardingsphere
時,在執(zhí)行sql查詢語句時報了一個異常:
### Cause: java.lang.NullPointerException
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
... 110 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.apache.shardingsphere.core.parse.antlr.rule.registry.ParsingRuleRegistry.findSQLStatementRule(ParsingRuleRegistry.java:117)
at org.apache.shardingsphere.core.parse.antlr.parser.SQLParserEngine.parse(SQLParserEngine.java:55)
at org.apache.shardingsphere.core.parse.antlr.AntlrParsingEngine.parse(AntlrParsingEngine.java:67)
at org.apache.shardingsphere.core.parse.SQLParsingEngine.parse(SQLParsingEngine.java:61)
at org.apache.shardingsphere.core.route.router.sharding.ParsingSQLRouter.parse(ParsingSQLRouter.java:78)
at org.apache.shardingsphere.core.route.PreparedStatementRoutingEngine.route(PreparedStatementRoutingEngine.java:64)
at org.apache.shardingsphere.core.PreparedQueryShardingEngine.route(PreparedQueryShardingEngine.java:60)
at org.apache.shardingsphere.core.BaseShardingEngine.shard(BaseShardingEngine.java:64)
at org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.shard(ShardingPreparedStatement.java:224)
at org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.execute(ShardingPreparedStatement.java:170)
根據(jù)異常信息,定位到ParsingRuleRegistry
的代碼愁拭,實際為集合parserRuleDefinitions
為空:
public Optional<SQLStatementRule> findSQLStatementRule(final DatabaseType databaseType, final String contextClassName) {
return Optional.fromNullable(parserRuleDefinitions.get(DatabaseType.H2 == databaseType ? DatabaseType.MySQL : databaseType).getSqlStatementRuleDefinition().getRules().get(contextClassName));
}
那么看集合 parserRuleDefinitions 是如何加載的望拖,為何為空蔓倍? 依次繼續(xù)定位到 ShardingParsingRuleRegistry
的 init 方法
public static ParsingRuleRegistry getInstance() {
if (null == instance) {
synchronized (ShardingParsingRuleRegistry.class) {
if (null == instance) {
instance = new ShardingParsingRuleRegistry();
instance.init();
}
}
}
return instance;
}
其中胰舆,在 instance.init()
方法中進行了來個類的數(shù)據(jù)初始化昨登,即:
protected final void init() {
initCommonParserRuleDefinition();
initParserRuleDefinition();
}
其中 initParserRuleDefinition 就是我們報空指針的集合的初始化的地方播演,于是在這兩個通過打斷點方式啟動調試冀瓦,調試時發(fā)現(xiàn),initParserRuleDefinition
沒有調用就結束了写烤,所以初步判定在 initCommonParserRuleDefinition
時發(fā)生了異常翼闽。
于是重點放在 initParserRuleDefinition
方法的追蹤,最終定位到一個 Method threw 'java.lang.ClassNotFoundException' exception.
異常信息洲炊,具體代碼為:
public final class FillerRuleDefinitionEntityLoader implements RuleDefinitionEntityLoader {
@Override
@SneakyThrows
public FillerRuleDefinitionEntity load(final String fillerRuleDefinitionFile) {
InputStream inputStream = FillerRuleDefinitionEntityLoader.class.getClassLoader().getResourceAsStream(fillerRuleDefinitionFile);
Preconditions.checkNotNull(inputStream, "Cannot load SQL filler rule definition file :%s, ", fillerRuleDefinitionFile);
return (FillerRuleDefinitionEntity) JAXBContext.newInstance(FillerRuleDefinitionEntity.class).createUnmarshaller().unmarshal(inputStream);//此行異常 ClassNotFoundException
}
}
這個地方比較坑人的時 這個異常并沒有在控制臺輸出感局,而是被shardingsphere吃掉了,所以比較難以定位暂衡。
解決
- 方法一:將 jdk的運行版本將為 1.8询微,我的默認是1.9所以出現(xiàn)了異常。
- 方法二:將 JAXB 相關jar包重新引入狂巢,具體maven
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>