- PR -

javax.xml.xpath.Xpath#evaluateでClassCastException

1
投稿者投稿内容
d@
会議室デビュー日: 2007/01/20
投稿数: 10
投稿日時: 2008-04-25 01:32
Sun JRE1.5 / Xerces-J 2.7.1を使用しXMLファイルを読み込んで
XPathを評価・値を取得するクラスを作成しました。

コード:

try{

  XPathFactory factory = XPathFactory.newInstance();
  XPath xpath = factory.newXPath();
  NodeList resultNodeList = (NodeList)xpath.evaluate("/hoge/hage/uge", dom, XPathConstants.NODESET);

}catch(XPathExpressionException e){
  throw e;
}



上記のような感じの実装になっているのですが、
これを“お客様のお客様の環境”で実行すると、
XPath評価結果をNodeListに変換するところでClassCastExceptionが発生しました。
スタックトレースには
「ClassCastException: java.util.ArrayList cannot be cast to org.w3c.dom.NodeList」
と出力されています。

JAXPおよびXercesのJavadocを読む限り、
Xpath#evaluateの第三引数でXPathConstants.NODESETを指定すると、
戻り値のObject型の実体はorg.w3c.dom.NodeListになるように見受けられますし、
自社に構築した環境と個人の開発端末では私の意図通り、NodeListにキャストして値を取得することができました。

特定環境のみでの現象、かつ、発生した環境は他社が構築したという事で
XPath評価の実装クラスが前述のXerces-J 2.7.1以外のものになってはいないか、と懸念しています。

現象が発生しているのはLinuxなので、
echo $CLASSPATHでパスが通っているか確認しましたが、
確かにxercesImpl-2.7.1.jarへのパスは通っていました。
現象が発生している環境の$JAVA_HOME/lib/jaxp.properiesはまだ未確認ですが、
おそらくデフォルト(未指定・プロパティファイル未作成)だと思われます。

というわけで、

・javax.xml.xpath.Xpath#evaluateで戻り値がArrayListになる場合は有り得ますか?
 (ArrayListで返却するようなXMLパーサは存在しますか?)
・クラスパスで特定のXMLパーサにパスを通しても、別のXMLパーサがJAXPにマップされる可能性は有り得ますか?
・その他チェックすべき項目があれば教えてください。


前述の通り、“お客様のお客様”所有の環境ということで、
直接触れることができず、情報収集に苦労しています。
お気づきの点があればご指摘いただけると嬉しいです。
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2008-04-25 09:16
引用:

・javax.xml.xpath.Xpath#evaluateで戻り値がArrayListになる場合は有り得ますか?
 (ArrayListで返却するようなXMLパーサは存在しますか?)



ドキュメントを読む限りでは、あってはならないですね。

引用:

・クラスパスで特定のXMLパーサにパスを通しても、別のXMLパーサがJAXPにマップされる可能性は有り得ますか?



ここにちょっと誤解があります。xercesImpl-2.7.1.jar は XPath の実装を提供していませんので、xercesImpl-2.7.1.jar をクラスパスに入れても XPath 実装は切り替わりません。
d@
会議室デビュー日: 2007/01/20
投稿数: 10
投稿日時: 2008-04-27 20:53
早速のご指摘ありがとうございます。

引用:

ここにちょっと誤解があります。xercesImpl-2.7.1.jar は XPath の実装を提供していませんので、xercesImpl-2.7.1.jar をクラスパスに入れても XPath 実装は切り替わりません。




Xerces-2.7.1にはXPath実装クラスが含まれていないということでしょうか?
XercesのJavadocにXPathインターフェースのドキュメントも含まれていたので
Xerces内部で実装クラスが提供されているものだと思い込んでいました。

となると、意図通りに動いている環境でも
実装クラスが何なのかが正確にはわからない、とうことになりますね。
JRE1.5が提供する標準XMLパーサ(com.sun.org.apache.xerces.internal.*のXerces??)が提供するクラスが使われているのでしょうか?

引き続き調査してみます。


[ メッセージ編集済み 編集者: d@ 編集日時 2008-04-27 22:43 ]
d@
会議室デビュー日: 2007/01/20
投稿数: 10
投稿日時: 2008-05-04 01:23
まだ完全解決したわけではないのですが、中間報告です。

現象が発生している環境で java -version を実施してもらったところ、
なんとJRE1.4が稼動していることが判明しました・・・。
(JAVA_HOMEがOSデフォルトのままだった??)

正しくJRE1.5が稼動するよう修正していただいた所、
件の現象は発生しなくなり、正常稼動するようになりました。


・・・ですが、JRE1.4だとevaluteメソッド戻り値の実態がArrayListというのが納得いかないです。

http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/xml/jaxp/JAXP-Compatibility_150.html にて
J2SE1.4(JAXP1.1)→ J2SE5(JAXP1.4)移行時の互換性についてがまとめられていますが、
XPathについては

引用:

javax.xml.xpath での Java 中心な XPath API。
XPath 表現を Java で使用しやすくなった。
インタフェースを実装しているあらゆるデータモデルに適用できるように設計されていた。
XPath API を使用してリファレンス実装の DOM を処理できるようになった。
将来は、JDom や STAX データモデルの処理時にも利用できるようになる予定



と記載されているのみで、
戻り値であるObject型の実装クラスが変更された旨の記載がありません。
現在、JAXP1.1 / CrimsonのJavadocを見つけることができていないのですが、
やはりArrayListで返却する仕様なのでしょうか?

[ メッセージ編集済み 編集者: d@ 編集日時 2008-05-04 01:26 ]
kuma
大ベテラン
会議室デビュー日: 2004/02/25
投稿数: 110
投稿日時: 2008-05-04 08:32
件のClassCastExceptionが発生しているのは本当に
コード:
NodeList resultNodeList = (NodeList)xpath.evaluate("/hoge/hage/uge", dom, XPathConstants.NODESET);


なのですか?
jre1.4がjavax.xml.xpath.XPathFactoryやXpathをどう解決しているのでしょう?
d@
会議室デビュー日: 2007/01/20
投稿数: 10
投稿日時: 2008-05-04 21:33
ClassCastExceptionが発生している箇所は
間違いなくevaluateメソッド実行とNodeListへのキャストを実行しているところです。
出力されたスタックトレースで行番号を確認・特定しました。

コード:
Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.w3c.dom.NodeList
   at age.moge.HogeXpath.getValues(HogeXpath.java:xx)



みたいな感じで出力されているので、これは間違いないと思います。

引用:


jre1.4がjavax.xml.xpath.XPathFactoryやXpathをどう解決しているのでしょう?



JRE1.4のJavadocを確認しましたが、
確かにXPath関連のクラスが含まれていないですね・・・。
javax.xml.xpath.XPathFactoryやXpathのクラス呼び出しが正常に行われた、ということは、
やはりJAXP1.1 / Crimsonではなく、JAXP1.4が動いていたということに・・・?
(そうでなければClassNotFoundExceptionになりそうなもんですし、
そもそも下位互換でエラーが発生したのであれば、version違い系のエラーが発生しそうな気が・・・)

現在、Java実行環境を好きにいじれるマシンが無いため
推測ばかりで申し訳ないのですが、引き続き調査・検証してみます。
ご指摘ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)