[Seasar-user:21032] Re: [S2DBCP]minPoolSizeを設定するとNullPointerExceptionが発生する

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2011年 9月 26日 (月) 17:46:09 JST


小林 (koichik) です.

報告ありがとうございます。
修正して SNAPSHOT をデプロイしたのでご確認ください。
# 修正は s2-extension のみ。

http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-framework/2.4.45-SNAPSHOT/s2-framework-2.4.45-20110926.084256-1.jar
http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-extension/2.4.45-SNAPSHOT/s2-extension-2.4.45-20110926.084256-1.jar
http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-tiger/2.4.45-SNAPSHOT/s2-tiger-2.4.45-20110926.084504-1.jar
http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2jdbc-gen/2.4.45-SNAPSHOT/s2jdbc-gen-2.4.45-20110926.084536-1.jar


Date: Mon, 26 Sep 2011 15:57:34 +0900
From: koba168 <[E-MAIL ADDRESS DELETED]>
Subject: [Seasar-user:21031] [S2DBCP]minPoolSizeを設定するとNullPointerExceptionが発生する

> お世話になります。小林と申します。
> 
> 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 mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user

--
{
  name: "Koichi Kobayashi",
  mail: "[E-MAIL ADDRESS DELETED]",
  blog: "http://d.hatena.ne.jp/koichik/",
  twitter: "@koichik"
 }



Seasar-user メーリングリストの案内