| XMLをXSLTするのに、Transformer クラスを使います。
これは TransformerFactoryクラスから 実装を取り出せます。
TransformerFactory.newInstance();
JDK1.4 では org.apache.xalan.processor.TransformerFactoryImpl
JDK5.0 では com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
が返ってくるようです。JDK5.0になって com.sun パッケージの実装になってみたいですね。
・・・が、JDK5.0 でも xalan.jar をクラスパスに含めて実行すると、 org.apache.xalan.processor.TransformerFactoryImpl になります。 この理由は JDKのAPIDocにあります〜 APIドキュメントによると 探し出す手順は以下になります。
xalan.jar の 中を見てみると・・・ ありますね、
META-INF/services/javax.xml.transform.TransformerFactory
のファイルが。
この中身を見てみると org.apache.xalan.processor.TransformerFactoryImpl と記述されてます。 ・・・これが有効になってたわけですね。
Factoryクラスによって、どの実装クラスを使うか? が指定できるのは便利な機能なんですが、それによって ハマることも。
たとえば、
tomcat5 上で 動かす Servlet にて Transformerをつかって XSLTしているプログラム。
JDK1.4でtomcatを動かすと、うまく動くのに、
JDK5.0でtomcatを動かすと、
Provider org.apache.xalan.processor.TransformerFactoryImpl not Found.
ってエラーがでる。
・・・・なーんて、悩んだ方いらっしゃるのでは?
これまでの話で ピンっと来た人も多い?
そぅ、この理由って
tomcat自体が使っている TransformerFactoryの実装は org.apache.xalan.processor.TransformerFactoryImpl を使っていた からだと思います。
JDK1.4では、たまたま(?) 上記クラスが JDKの中に含まれていたので大丈夫でしたが、JDK5.0では 含まれていないので エラー になったんですね。
この場合の解決方法としては 大きく2種類。
一つ目は
org.apache.xalan.processor.TransformerFactoryImpl
がある xalan.jar とかを tomcat上のlibにいれちゃって、org.apacheパッケージを使うようにしちゃう。
二つ目は
JDK5.0に含まれている
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
を使ってくれるような設定にしちゃう。
設定方法は JDKのAPIドキュメント通りなんですが、方法によりけりtomcatに影響があるかもしんない。
たとえば、システムプロパティに追加
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
って方法や JREのlib/jaxp.properties に追加する方法。
一応できるけど、システムプロパティに追加した時点で、tomcatを含むそのVM上の全てのプログラムに影響がいく?
んじゃー無難な線として
作成したJARの META-INF/services/javax.xml.transform.TransformerFactory
のファイルで
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
指定しちゃう。
JDK1.4で動かされたときには アウト ですけどもね。。
JDK1.4、5.0両方で動作OKのものを作るためには・・・
ほんと妥協して Factoryクラスを使うんじゃなくて、使いたい Transformer クラスを自分でインスタンスしちゃう のが一番確実かもしんないなぁー |