[Seasar-user:21031] [S2DBCP]minPoolSizeを設定するとNullPointerExceptionが発生する
koba168
[E-MAIL ADDRESS DELETED]
2011年 9月 26日 (月) 15:57:34 JST
お世話になります。小林と申します。
S2DBCPのコネクションプーリング機能でNullPointerExceptionが発生するケース
が見つかりましたので報告いたします。
環境:
Seasar2 2.4.44
jdbc.dicon:
<component name="connectionPool"
class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
<property name="timeout">60</property>
<property name="maxPoolSize">10</property>
<property name="minPoolSize">1</property>
<property name="allowLocalTx">true</property>
<destroyMethod name="close"/>
</component>
スタックトレース:
java.lang.NullPointerException
at org.seasar.extension.dbcp.impl.ConnectionPoolImpl.checkOutFreePool(ConnectionPoolImpl.java:400)
at org.seasar.extension.dbcp.impl.ConnectionPoolImpl.checkOut(ConnectionPoolImpl.java:364)
at org.seasar.extension.dbcp.impl.DataSourceImpl.getConnection(DataSourceImpl.java:59)
at org.seasar.doma.internal.jdbc.util.JdbcUtil.getConnection(JdbcUtil.java:40)
at org.seasar.doma.internal.jdbc.command.SelectCommand.execute(SelectCommand.java:53)
... 以下省略 ...
再現させる手順ですがminPoolSizeに1以上の値を設定した状態で
1. プールされたコネクションがtimeoutで指定された時間を経過
2. expired処理実行。プールされたコネクション数がminPoolSizeを下回りプールから削除しない
3. そのコネクションをプールから取得して使用する
の流れでNullPointerExceptionが発生します。
ソースを確認したところ以下のexpiredの処理が問題だと思われます。
org.seasar.extension.dbcp.impl.ConnectionPoolImpl$FreeItem#expired()
public void expired() {
synchronized (ConnectionPoolImpl.this) {
if (freePool.size() > minPoolSize) {
freePool.remove(this);
}
}
synchronized (this) {
if (timeoutTask_ != null) {
timeoutTask_.cancel();
timeoutTask_ = null;
}
if (connectionWrapper_ != null) {
connectionWrapper_.closeReally();
connectionWrapper_ = null;
}
}
}
freePoolのサイズがminPoolSizeを下回る場合に、freePool.remove(FreeItem)は呼ばれないが
FreeItemの内部変数として保持しているconnectionWrapper_については必ずクローズしてnullを設定するので
次回、このFreeItemがfreePoolリストから取り出されてconnectionWrapper_が使用されるときに
NullPointerExceptionが発生する。
とりあえずこの部分を修正してこの問題は回避しています。
よろしくお願いいたします。
Seasar-user メーリングリストの案内