[mayaa-user:991] Re: pageSerializeを有効にすると、時々裏で例外が発生します

Susumu ISHIGAMI [E-MAIL ADDRESS DELETED]
2013年 9月 8日 (日) 00:11:07 JST


石上です。

TemplateImplを継承した独自のTemplateImplを作成し、serializeをOverrideして

@Override
public void serialize() {
  try {
    super.serialize();
  } catch (ConcurrentModificationException e) {
    System.out.println(this.getSystemID());
    throw e;
  }
}

と記述してみたところ、テンプレートファイルのSystemID(ファイル名)が出力されましたので、
TemplateImpl内のserializeで発生しているようです。

serializeメソッドでConcurrentModificationExceptionをcatchして握りつぶした場合、
SerializeThread.runのループが継続し、今のままthrowさせておくと、
ループが中断する違いがありますが、こちらはどちらの方がより望ましいでしょうか。

>> synchronized(specification) {
>> があるので一見すると競合は発生しないように思えますが、
>
>推測の域を出ませんが、そこに渡しているオブジェクトの内部のListを操作しているのが問題です。
>serializeとリビルドのタイミングが重なっているのではないかと思うのですが。

Listは、例えば、mayaaファイルやmjsファイルの変数として定義したものも含まれますでしょうか?

TemplateImpl.javaに
private List _childProcessors = new ArrayList();
が含まれていますので、こちらを
private List _childProcessors = Collections.synchronizedList(new ArrayList());
とすれば、効果はあるでしょうか。


細かい質問で申し訳なく思います。
ユーザーに実害がないとのことなので、このままにしておこうと思います。
こちらでも調査が進みましたら情報を共有致します。

2013年9月2日 22:39 suga <ko.suga @ gmail.com>:
> suga です。
>
> 2013/9/2 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>:
>> synchronized(specification) {
>> があるので一見すると競合は発生しないように思えますが、
>
> 推測の域を出ませんが、そこに渡しているオブジェクトの内部のListを操作しているのが問題です。
> serializeとリビルドのタイミングが重なっているのではないかと思うのですが。
>
>
>> もしこの例外を無視したければ、
>> SpecificationImplのserializeをOverrideするのが良いのではないかと思います。
>> この時、例外時は以下のようにリトライする対策を行うことには意味がありますでしょうか?
>
> リトライは不要です。
> 別口で成功していれば当然不要ですし、そうでなくても次のビルド時にはシリアライズされますので。
>
> もし仮に失敗しているものが破棄されるオブジェクトの場合、変な状態のものがシリアライズされることになります。
>
> --
> suga ( ko.suga @ gmail.com )
>
>
> 2013/9/2 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>:
>> 石上です。
>> ご回答ありがとうございます。
>>
>> org.seasar.mayaa.impl.engine.specification.serialize.SerializeThread.run()
>>>> synchronized(specification) {
>> があるので一見すると競合は発生しないように思えますが、
>> specificationを多段化が原因で発生しているのかもしれませんね。
>> (中間のSpecificationが別のページでも使われている等)
>>
>> もしこの例外を無視したければ、
>> SpecificationImplのserializeをOverrideするのが良いのではないかと思います。
>> この時、例外時は以下のようにリトライする対策を行うことには意味がありますでしょうか?
>>
>> for (int i = 0; i < RETRY_MAX; i++) {
>>   try {
>>     super.serialize();
>>     break;
>>   } catch (ConcurrentModificationException e) {
>>     continue;
>>   }
>> }
>>
>> 細かいところで申し訳ありません。
>>
>>
>> 2013年9月1日 20:19 suga <ko.suga @ gmail.com>:
>>> suga です。
>>>
>>> 同じファイルに対して出続けるということでなければ、ユーザへの実害は無いと思います。
>>>
>>> 現象としてはおそらく同じSpecificationImplに対するビルドが瞬間的に複数回実行されて、
>>> 古いものをdeleteする処理とSerializeThreadでのserializeが同時に、というところだと思います。
>>>
>>> --
>>> suga ( ko.suga @ gmail.com )
>>>
>>>
>>> 2013/8/31 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>:
>>>> 石上です。
>>>> いつもお世話になっております。
>>>>
>>>> 既知の問題であったら申し訳ありません。
>>>> pageSerialize機能を有効にした状態で、
>>>> ページ遷移を繰り返していると下記のExceptionが時々ログ上に現れます。
>>>>
>>>> 自分のアプリケーションが起因しているかもしれませんが、
>>>> スタックトレースには、Java標準とMayaaのクラスしか現れません。
>>>>
>>>> おそらく、ページにシリアライズ処理が競合し
>>>> 実際はシリアライズが一回行われない程度で、
>>>> ユーザーには影響がほぼないのではないかと思います。
>>>> しかし、念のため、問題ないか確認したいことと、
>>>> 問題ないのであったら、ログファイルにスタックトレースを出力せず、
>>>> 綺麗にしたいと思っています。
>>>>
>>>> JDK 1.7.0、Tomcat7.0で発生しています。
>>>>
>>>> よろしくお願い致します。
>>>>
>>>> Exception in thread "serializeThread-0"
>>>> java.util.ConcurrentModificationException
>>>> at java.util.ArrayList.writeObject(ArrayList.java:713)
>>>> at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
>>>> at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
>>>> at org.seasar.mayaa.impl.engine.processor.TemplateProcessorSupport.writeObject(TemplateProcessorSupport.java:254)
>>>> at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
>>>> at java.util.ArrayList.writeObject(ArrayList.java:710)
>>>> at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
>>>> at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
>>>> at org.seasar.mayaa.impl.engine.processor.TemplateProcessorSupport.writeObject(TemplateProcessorSupport.java:254)
>>>> at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
>>>> at java.util.ArrayList.writeObject(ArrayList.java:710)
>>>> at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
>>>> at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
>>>> at org.seasar.mayaa.impl.engine.processor.TemplateProcessorSupport.writeObject(TemplateProcessorSupport.java:254)
>>>> at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
>>>> at java.util.ArrayList.writeObject(ArrayList.java:710)
>>>> at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
>>>> at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
>>>> at org.seasar.mayaa.impl.engine.processor.TemplateProcessorSupport.writeObject(TemplateProcessorSupport.java:254)
>>>> at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
>>>> at java.util.ArrayList.writeObject(ArrayList.java:710)
>>>> at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
>>>> at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
>>>> at org.seasar.mayaa.impl.engine.processor.TemplateProcessorSupport.writeObject(TemplateProcessorSupport.java:254)
>>>> at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
>>>> at java.util.ArrayList.writeObject(ArrayList.java:710)
>>>> at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
>>>> at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
>>>> at org.seasar.mayaa.impl.engine.processor.TemplateProcessorSupport.writeObject(TemplateProcessorSupport.java:254)
>>>> at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
>>>> at java.util.ArrayList.writeObject(ArrayList.java:710)
>>>> at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
>>>> at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
>>>> at org.seasar.mayaa.impl.engine.TemplateImpl.writeObject(TemplateImpl.java:325)
>>>> at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>> at java.lang.reflect.Method.invoke(Method.java:601)
>>>> at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
>>>> at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
>>>> at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
>>>> at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
>>>> at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
>>>> at org.seasar.mayaa.impl.engine.specification.SpecificationImpl.serialize(SpecificationImpl.java:302)
>>>> at org.seasar.mayaa.impl.engine.specification.serialize.SerializeThread.run(SerializeThread.java:81)
>>>>
>>>> --
>>>> Susumu ISHIGAMI
>>>> susumu.ishigami @ gmail.com
>>>> _______________________________________________
>>>> mayaa-user mailing list
>>>> mayaa-user @ ml.seasar.org
>>>> https://ml.seasar.org/mailman/listinfo/mayaa-user
>>> _______________________________________________
>>> mayaa-user mailing list
>>> mayaa-user @ ml.seasar.org
>>> https://ml.seasar.org/mailman/listinfo/mayaa-user
>>
>>
>>
>> --
>> Susumu ISHIGAMI
>> susumu.ishigami @ gmail.com



-- 
Susumu ISHIGAMI
susumu.ishigami @ gmail.com


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