[Seasar-user:20297] [S2Container]マルチスレッド処理時にCyclicReferenceRuntimeException

[E-MAIL ADDRESS DELETED] [E-MAIL ADDRESS DELETED]
2010年 11月 1日 (月) 18:00:34 JST


お世話になります、齊藤と申します。

現在、S2Containerを使った、
マルチスレッドによるバッチ処理の検証を行っております。

その検証の中で、稀にですが、
CyclicReferenceRuntimeExceptionが発生することがあります。
この例外が発生する原因、および解決策をご教授願いたく。

以下、検証時の大まかな構成と、
現時点で分かっている情報になります。



●検証で利用したS2のバージョン
 ・S2Framework 2.4.39
 ・S2Extension 2.4.39
 ・S2Tiger     2.4.39


●検証用アプリの構造(diconファイルに登録した主要コンポーネントのみ抜粋)

 Aクラス(instance="ptototype") -------> Bクラス(instance="prototype"
)
                          ↑
                                Bクラス用InterceptorAdapter(
以下のInterceptorを保持、Bクラスにaspect)
                       - CInterceptor(
instance="prototype")
                       - DInterceptor(
instance="prototype")
                         - Eクラス(
instance="singleton"、Stringフィールドを複数保持するBeanクラス、
DInterceptorにDI)

  ※上記AクラスからBクラスの呼び出しを、複数スレッドで同時に実行
   今回の検証では、1回の処理で同時に10スレッド実行


●発生する例外の詳細(一部加工しています)

org.seasar.framework.beans.IllegalPropertyRuntimeException: [ESSR0059]クラ
ス(DInterceptor)のプロパティ(Eクラス)の設定に失敗しました。理由は
org.seasar.framework.container.CyclicReferenceRuntimeException: 
[ESSR0047]Eクラスで循環参照が発生しました
        at 
org.seasar.framework.container.assembler.AbstractBindingTypeDef.getValue(AbstractBindingTypeDef.java:297)
        at 
org.seasar.framework.container.assembler.AbstractBindingTypeDef.bindAuto(AbstractBindingTypeDef.java:149)
        at 
org.seasar.framework.container.assembler.BindingTypeMustDef.doBind(BindingTypeMustDef.java:45)
        at 
org.seasar.framework.container.assembler.AbstractBindingTypeDef.bind(AbstractBindingTypeDef.java:91)
        at 
org.seasar.framework.container.assembler.AccessTypeFieldDef.bind(AccessTypeFieldDef.java:50)
        at 
org.seasar.framework.container.assembler.AccessTypeFieldDef.bind(AccessTypeFieldDef.java:42)
        at 
org.seasar.framework.container.assembler.AutoPropertyAssembler.assemble(AutoPropertyAssembler.java:56)
        at 
org.seasar.framework.container.deployer.PrototypeComponentDeployer.deploy(PrototypeComponentDeployer.java:43)
        at 
org.seasar.framework.container.impl.ComponentDefImpl.getComponent(ComponentDefImpl.java:111)
        at 
org.seasar.framework.aop.interceptors.InterceptorAdapter.invoke(InterceptorAdapter.java:67)
        at Bクラス
$$EnhancedByS2AOP$$19a37a$$MethodInvocation$$execute2.proceed(MethodInvocationClassGenerator.java)
        at Bクラス$$EnhancedByS2AOP$$19a37a.execute(Bクラス
$$EnhancedByS2AOP$$19a37a.java)
        at Aクラス.execute(Bクラス.java:999)
        (中略)
Caused by: org.seasar.framework.container.CyclicReferenceRuntimeException: 
[ESSR0047]Eクラスで循環参照が発生しました
        at 
org.seasar.framework.container.deployer.SingletonComponentDeployer.assemble(SingletonComponentDeployer.java:59)
        at 
org.seasar.framework.container.deployer.SingletonComponentDeployer.deploy(SingletonComponentDeployer.java:48)
        at 
org.seasar.framework.container.impl.ComponentDefImpl.getComponent(ComponentDefImpl.java:111)
        at 
org.seasar.framework.container.impl.S2ContainerImpl.getComponent(S2ContainerImpl.java:129)
        at 
org.seasar.framework.container.assembler.AbstractBindingTypeDef.getValue(AbstractBindingTypeDef.java:295)
        (以下略)


●発生する例外の補足
 ・上記例外は、20回に1回出るか出ないかくらいの頻度で発生
 ・最新のS2のバージョンでも、同様の例外が発生するのを確認
 ・「循環参照が発生」と出るが、上記EクラスはStringのみ保持、かつDIしてい
るフィールドはない
 ・Eクラスから別のクラス(instanceはsingleton)に差し替えても、同様の例外
が発生することがある
   ・prototypeのコンポーネントにsingletonのコンポーネントをDIするときに
発生する模様
 ・Bクラス用InterceptorAdapterをInterceptorChainに変更すると、上記例外が
発生しない
   ・試行回数が少ないだけ?
   ・Interceptorのinstanceはprototypeにしたいため、できれば
InterceptorAdapterを使いたい
 ・シングルスレッド時には、上記例外は発生しない


●原因に関する個人的見解
 ・org.seasar.framework.container.deployer.SingletonComponentDeployerにて
、
  以下の順序で処理が走ったのではないか、と予想

   1. スレッド1・スレッド2がほぼ同時に
SingletonComponentDeployer#deploy()メソッドを呼び出す
   2. 1.の時点でcomponentフィールドはnullのため、
     スレッド1・スレッド2共に47行目のif文がtrueとなり、assemble()メソ
ッドを呼び出す(48行目)
   3. スレッド1が62行目を先に呼び出して、instantiatingフィールドにtrue
をセットする
   4. スレッド2が58行目に到達、3によりinstantiatingフィールドがtrueにさ
れたため59行目に到達
     → 上記例外発生



長くなりましたが、
上記問題への対応策等をご教授頂けますでしょうか?

以上、よろしくお願い致します。

==========
齊藤 雅志
-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: <http://ml.seasar.org/archives/seasar-user/attachments/20101101/027629a6/attachment.html>


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