DITAのお守り⇒パーサーこけた!

DITAでCMSを使っているお客様からみると、すべてはCMSGUIから行われるので、PDF出力なんてCMSのPublication managerの一つの機能に過ぎません.なのでましてやDITA Open Toolkitなんて言ったらいくらそれがオープンソースだと説明しても障害があると全部プラグインの担当の私のところに回ってきます.まあ仕方ないですが...

で、今回「動きません!」と送られてきたのは次のようなログでした.
 
gen-list-without-flagging:
 [pipeline] Using XERCES.
 [pipeline] Using Xerces grammar pool for DTD and schema caching.
 [pipeline] [DOTJ013E][ERROR] Failed to parse the referenced file 'XXXXXXXX.xml' due to below exception. Please correct the reference base on the exception message.
 [pipeline] String index out of range: -1
 
わが女房は「Stringの使い方が悪いんじゃないの?」なんて他人事のように言います.確かにそうなのでしょう.でも問題はこの例外がどこで起こっているかです.
 
まずこのXXXXXXXX.xmlですがたった数十ステップ程度のDITAインスタンスでもちろんvalidです.このファイルが原因とはとても考えられません.また同じビルドを私のところで何回やっても起こらないのです.仕方がないので、DITA-OTのソースを"DOTJ013E"でgrepしてみると、このメッセージを出しているは以下の4箇所しかないのがわかりました.
 
org\dita\dost\module\GenMapAndTopicListModule.java(477): msg = MessageUtils.getMessage("DOTJ013E", params).toString();
org\dita\dost\module\GenMapAndTopicListModule.java(490): msg = MessageUtils.getMessage("DOTJ013E", params).toString();
org\dita\dost\module\IndexTermExtractModule.java(240): msg = MessageUtils.getMessage("DOTJ013E", params).toString();
org\dita\dost\module\IndexTermExtractModule.java(274): msg = MessageUtils.getMessage("DOTJ013E", params).toString();
 
どうも下の2つは関係なさそうです.上の2箇所で何をやっているか見ると、SAXでDITAインスタンスをパースしています.そこでtry~catchで例外を拾ってこのメッセージとなっています.ということは、"String index out of range: -1"の例外はパーサーのXercesの中で発生していることは間違いないのではないかという結論に至りました.つまりパーサーが「こけて」いるのです.
 
お客さんの報告では、ほとんどのビルドでうまくいき、同じターゲットのビルドでも起こる場合も起こらない場合もあるとのことです.こうなると非常に厄介です.いくらオープンソースだからといってもXercesをデバッグする体力はありません.
 
結局、JRE6を最新のupdate 30にしてもらったのですが、それでもやはり発生してしまうビルドがあるようです.
DITA-OTは確か1.5.1くらいからパーサーのXercesにスキーマDTD)をキャッシングさせる機能をつけています.それより前のDITA-OTはそんな機能ありませんでした.どうもこれが例外の原因じゃないかと推測しました.これに基づいて、DITA-OT1.5.1でキャッシングさせているところをコメントにしてdost.jarをお客さんに送る提案をしたんですが、もうすぐDITA-OTを1.5.3に上げるから不要という返事です(せっかくビルドしてテストしたのに!).DITA-OT1.5.3では、コマンドラインの-Dargs.grammar.cache=noでキャッシュを止める指定ができます.(1.5.1ではできない)DITA-OT1.5.3ではこれを試してもらうようにお願いしました.
 
実はパーサーのXercesはDITA Open Toolkitにバンドルされているものより新しいのを使っています.Antを1.8.2にする必要があったので、その際に最新版がいいだろうとApacheから落としたのですが、これが影響したのかもしれません.という訳で、当分はDITA-OTのお守りが続きます.