Notes/Domino6.5のJavaでのDOM Level2/SAX2の利用
Notes/Domino6.5でDOM Level2/SAX2を利用するには、外部の実装が必要です。しかし、ただ設計要素に含めれば利用出来るというわけではありません。
・DOMに関する問題点
「DOM Level2」を利用する上での問題点は、「XML4J.jar」がブートストラップクラスパスに含まれていることです。「XML4J.jar」には「org.w3c.dom」パッケージのインターフェイスクラスと、それらインターフェイスの実装クラスが含まれます。
「DOM Level2」は、従来からあるインターフェイスに名前空間を扱うメソッドを追加する形で拡張しています。「DOM Level2」の機能を利用するJavaプログラムは、「DOM Level2」の仕様に則ったインターフェイスクラスをロードしなくてはいけません。
適当なデータベースにJavaエージェントを作成し、「プロジェクトの編集」で「DOM Level2」の実装をエージェントに含めます。この例では「APACHE XML」プロジェクトの「Xerces2」を用いています。
「org.w3c.dom.Document」オブジェクトを構築するコード(例えば以下のコード)を用意します。
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder dbuilder = dbf.newDocumentBuilder();
org.w3c.dom.Document domdoc = dbuilder.newDocument();
...
そして、「org.w3c.dom.Document」オブジェクトの実装クラス、「DOM Level2」で追加されたメソッドを持っているかを確認するコード(例えば以下のコード)を用意します。
...
System.out.println("実装クラス:" + domdoc.getClass().getName());
Class[] params = {String.class,String.class};
Method method = domdoc.getClass().getMethod("createElementNS",params);
System.out.println("シグネチャ:" + method);
...
ノーツクライアントで実行すると以下のような内容が得られます。
実装クラス:org.apache.xerces.dom.DocumentImpl
シグネチャ:public org.w3c.dom.Element org.apache.xerces.dom.CoreDocumentImpl.createElementNS(java.lang.String,java.lang.String) throws org.w3c.dom.DOMException
Xerces2が持つJAXPの実装を利用して「org.w3c.dom.Document」オブジェクトを構築しているので、オブジェクトの実装クラスもXerces2に由来するものとなっています。構築されたオブジェクト自身は「DOM Level2」で追加されたメソッドを実装しています。
続いて、「org.w3c.dom.Document」インターフェイスクラスが、「DOM Level2」で追加されたメソッドを持っているかを確認するコード(例えば以下のコード)を用意します。
...
Method method = org.w3c.dom.Document.class.getMethod("createElementNS",params);
System.out.println("シグネチャ:" + method);
...
ノーツクライアントでこのコードが実行されると以下のような例外が発生します。
java.lang.NoSuchMethodException: createElementNS
at java.lang.Class.getMethod0(Native Method)
at java.lang.Class.getMethod(Class.java:928)
at ChkDomAgent.NotesMain(ChkDomAgent.java:40)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(NotesThread.java:215)
ロードされている「org.w3c.dom.Document」インターフェイスクラスには、「DOM Level2」で追加されたメソッドはありません。Xerces2には「DOM Level2」に則った各インターフェイスクラスが含まれています。しかし、ブートストラップクラスパス上にある「XML4J.jar」から古いインターフェイスクラスロードされてしまい、Xerces2からはロードされません。
つまりドミノデザイナーでは以下のコードはコンパイルできません。
domdoc.createElementNS("element","urn:foo");
・利用するには
少なくとも「DOM Level2」に則った各インターフェイスクラスを、クラスパス上でXML4J.jarより前に置かなくてはいけません。そのためにはNotes.iniパラメータ「JavaUserClasses」を利用する必要があります。JavaUserClassesでXerces2等の実装を指定することで、ブートストラップ上のより前の位置にエントリを追加することができ、最初に見つかる各インターフェイスクラスを「DOM Level2」に則ったものにすることができます。
これにより「DOM Level2」の機能が使えるようになり、先のドミノデザイナーでコンパイルできないコードの例もコンパイルできるようになります。
・考慮点
Notes/Domino6.5に含まれるクラスと、「DOM Level2」の実装を含んだパッケージのクラスが衝突していないことを確認しなくてはいけないと思いますが、あまり無いと思われます。
また、各インターフェイスクラスが「DOM Level2」に則ったものに変わったことによる、Notes/Domino6.5の動作への影響は無いと考えます。追加された要素はあっても、削除されたものは無いからです。
考慮点としては、インターフェイスクラスが「DOM Level2」に則ったものでも、Notes/Domino6.5が提供する実装クラスは「DOM Level2」に対応していないということです。
Notes/Domino6.5の機能からDOMオブジェクトを受け取り、「DOM Level2」で追加されたメソッドを実行するコードを(例えば以下のコード)を用意します。
...
lotus.domino.Item notesItem = ...;
org.w3c.dom.Document domDoc = notesItem.parseXML(false);
org.w3c.dom.Element rootElement = domDoc.getDocumentElement();
org.w3c.dom.Attr attr = rootElement.getAttributeNodeNS("urn:foo","branch");
...
通常ならばドミノデザイナーでコンパイルすることはできないコードですが、「DOM Level2」の実装を利用できる状態であればコンパイルすることができます。しかし実行すると例外が発生します。
java.lang.AbstractMethodError: com/ibm/xml/dom/ElementImpl.getAttributeNodeNS
at ChkDomAgent2.NotesMain(ChkDomAgent2.java:39)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(NotesThread.java:215)
Notes/Domino6.5の機能から受け取るDOMオブジェクトは、「XML4J.jar」に由来する実装クラスだからです。
Javaにより構築された、XMLを利用するさまざまなツールを現在入手することが出来ます。そのような他のJavaのプログラム等に、Notes/Domino6.5の機能から受け取るDOMオブジェクトを引き渡すような場合、一旦文字列にした後、再度「DOM Level2」の実装によりDOMオブジェクトを構築する必要があると思われます。
・SAX2を利用する
「DOM Level2」と違い「SAX2」の場合は、新しくインターフェイスを用意することで機能追加が行われており、既存のものは変更されていません。その為「DOM Level2」のように、Notes.iniパラメータ「JavaUserClasses」を使ってインターフェイスクラスをブートストラップクラスパスの前の方に、といった事は必要ありません。
「APACHE XML」プロジェクトの「Xerces2」のような、各インターフェイスクラスを含めたSAX2の実装を、JavaエージェントやJavaスクリプトライブラリ等、データベースの設計要素のレベルで含めるだけで十分です。
そうすれば「org.xml.sax.XMLReader」インターフェイス等、SAX2で追加されたインターフェイスも問題なく利用でき、よほど特異な実装をしていない限り(例えば「DOM Level2」を利用して「SAX2」を実装している等、普通は逆だと思われます)、SAX2の実装が利用出来ると思います。
もちろん、Notes.iniパラメータ「JavaUserClasses」を用いてブートストラップクラスパスに含めても、拡張機能ディレクトリに配置しても問題は無いと思います。
・最後に
一番利用されるであろう実装はXerces2だと思います。Xerces2では「DOM Level2」と「SAX2」の実装はひとまとまりになっています。Xerces2を用いて「DOM Level2」「SAX2」を利用するとしても、各クライアントのローカルディスクに実装を保存するという作業は、それらの更新のことを含めて、とても大変だと思います。
実際のところ、ドミノサーバー上にXerces2等の「DOM Level2」「SAX2」の実装を配置して、サーバーエージェントでのバックグラウンド的処理に利用するというのが現実的なのかと思います。
留意点は、そのままDomino7にアップグレードしたとき、JRE1.4が持つXML操作関連の実装が利用されないかもしれないということです。その方が望ましいという場合も当然あると思います。さすがに、あいかわらず「XML4J.jar」が同じように存在していてインターフェイスクラスが・・・、ということは無いとは思うのですが。
※上記の内容は、あくまでSakamotoの個人的な興味、好奇心より確かめた内容であり、またあくまで個人的な意見です。参考になさる場合はご自身の責任においてお願いいたします。Sakamotoは一切責任を負いません。
Sakamotoは上記の内容の正誤に関する保証、上記の内容に関するサポートは行いません。またこの旨を伝える返信等も行いません。
| 固定リンク

