<p dir="auto">java.lang.NullPointerException: null<br>
at org.apache.shardingsphere.core.execute.sql.execute.result.MemoryQueryResult.getRowValue(MemoryQueryResult.java:88) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.sql.execute.result.MemoryQueryResult.getRows(MemoryQueryResult.java:63) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.sql.execute.result.MemoryQueryResult.(MemoryQueryResult.java:55) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor.getQueryResult(PreparedStatementExecutor.java:116) ~[sharding-jdbc-core-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor.access$200(PreparedStatementExecutor.java:50) ~[sharding-jdbc-core-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor$2.executeSQL(PreparedStatementExecutor.java:106) ~[sharding-jdbc-core-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor$2.executeSQL(PreparedStatementExecutor.java:102) ~[sharding-jdbc-core-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.sql.execute.SQLExecuteCallback.execute0(SQLExecuteCallback.java:79) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.sql.execute.SQLExecuteCallback.execute(SQLExecuteCallback.java:61) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.engine.ShardingExecuteEngine.syncGroupExecute(ShardingExecuteEngine.java:125) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.engine.ShardingExecuteEngine.parallelExecute(ShardingExecuteEngine.java:102) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.engine.ShardingExecuteEngine.groupExecute(ShardingExecuteEngine.java:83) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.sql.execute.SQLExecuteTemplate.executeGroup(SQLExecuteTemplate.java:73) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.core.execute.sql.execute.SQLExecuteTemplate.executeGroup(SQLExecuteTemplate.java:56) ~[sharding-core-execute-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.shardingjdbc.executor.AbstractStatementExecutor.executeCallback(AbstractStatementExecutor.java:140) ~[sharding-jdbc-core-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor.executeQuery(PreparedStatementExecutor.java:109) ~[sharding-jdbc-core-4.0.0.jar:4.0.0]<br>
at org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.executeQuery(ShardingPreparedStatement.java:123) ~[sharding-jdbc-core-4.0.0.jar:4.0.0]</p>
<p dir="auto">version : 3.0.0.M1<br>
project : sharding-jdbc</p>
<p dir="auto">Expected behavior : when table rule not define , sharding-jdbc create it and put it into cache</p>
<p dir="auto">Actual behavior :  when logicTableName not found in tableRules, sharding-jdbc will create table rule and not put it into cache , It will run groovy script . If this sql run many times , will create many groovy classlaoder. After that will got "java.lang.OutOfMemoryError:Permgen space" error.</p>
<p dir="auto">Reason :<br>
I debug and found this code.</p>
<p dir="auto">// class  io.shardingsphrer.cor.rule.ShardingRule</p>
<hr>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="public Optional&lt;TableRule&gt; tryFindTableRuleByActualTable(final String actualTableName) {
	for (TableRule each : tableRules) {
		if (each.isExisted(actualTableName)) {
			return Optional.of(each);
		}
	}
	return Optional.absent();
}


public TableRule getTableRuleByLogicTableName(final String logicTableName) {
	Optional&lt;TableRule&gt; tableRule = tryFindTableRuleByLogicTable(logicTableName.toLowerCase());
	if (tableRule.isPresent()) {
		return tableRule.get();
	}
	if (!Strings.isNullOrEmpty(shardingDataSourceNames.getDefaultDataSourceName())) {
		return new TableRule(shardingDataSourceNames.getDefaultDataSourceName(), logicTableName);
	}
	throw new ShardingConfigurationException(&quot;Cannot find table rule and default data source with logic table: '%s'&quot;, logicTableName);
}"><pre class="notranslate"><span class="pl-k">public</span> <span class="pl-smi">Optional</span>&lt;<span class="pl-smi">TableRule</span>&gt; <span class="pl-s1">tryFindTableRuleByActualTable</span>(<span class="pl-k">final</span> <span class="pl-smi">String</span> <span class="pl-s1">actualTableName</span>) {
	<span class="pl-k">for</span> (<span class="pl-smi">TableRule</span> <span class="pl-s1">each</span> : <span class="pl-s1">tableRules</span>) {
		<span class="pl-k">if</span> (<span class="pl-s1">each</span>.<span class="pl-en">isExisted</span>(<span class="pl-s1">actualTableName</span>)) {
			<span class="pl-k">return</span> <span class="pl-smi">Optional</span>.<span class="pl-en">of</span>(<span class="pl-s1">each</span>);
		}
	}
	<span class="pl-k">return</span> <span class="pl-smi">Optional</span>.<span class="pl-en">absent</span>();
}


<span class="pl-k">public</span> <span class="pl-smi">TableRule</span> <span class="pl-s1">getTableRuleByLogicTableName</span>(<span class="pl-k">final</span> <span class="pl-smi">String</span> <span class="pl-s1">logicTableName</span>) {
	<span class="pl-smi">Optional</span>&lt;<span class="pl-smi">TableRule</span>&gt; <span class="pl-s1">tableRule</span> = <span class="pl-en">tryFindTableRuleByLogicTable</span>(<span class="pl-s1">logicTableName</span>.<span class="pl-en">toLowerCase</span>());
	<span class="pl-k">if</span> (<span class="pl-s1">tableRule</span>.<span class="pl-en">isPresent</span>()) {
		<span class="pl-k">return</span> <span class="pl-s1">tableRule</span>.<span class="pl-en">get</span>();
	}
	<span class="pl-k">if</span> (!<span class="pl-smi">Strings</span>.<span class="pl-en">isNullOrEmpty</span>(<span class="pl-s1">shardingDataSourceNames</span>.<span class="pl-en">getDefaultDataSourceName</span>())) {
		<span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">TableRule</span>(<span class="pl-s1">shardingDataSourceNames</span>.<span class="pl-en">getDefaultDataSourceName</span>(), <span class="pl-s1">logicTableName</span>);
	}
	<span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-smi">ShardingConfigurationException</span>(<span class="pl-s">"Cannot find table rule and default data source with logic table: '%s'"</span>, <span class="pl-s1">logicTableName</span>);
}</pre></div>
<hr>
<p dir="auto">tableRule isPresent and create new one . Cache it into tableRules than everytime create it .<br>
When someone make a mistake and publish to production env , will be a disaster.This is not friendly for developers.</p>