読者です 読者をやめる 読者になる 読者になる

java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory

Java XStream

公式チュートリアルではこう書いてある。

You require xstream-[version].jar and kxml2-min-[version].jar in the classpath. kXML2 is a very fast XML pull-parser implementation. If you do not want to include this dependency, you can use a standard JAXP DOM parser or since Java 6 the integrated StAX parser instead:

つまり標準で使用する場合は、XStreamのJarとkXML2-min版Jarをクラスパスに入れろ、ということらしい。
しかし、実際に[DownLoad]にあるStable Version: 1.4.1 "Binary distribution"をDLして
上記Jarをクラスパスに入れて実行すると、

Exception in thread "main" java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory

と言われてしまう。
kxml2-min-2.3.0.jarの中身を覗いてみても、Factoryクラスは入っていない。

$ jar -tf kxml2-min-2.3.0.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/kxml2/
org/kxml2/io/
org/kxml2/io/KXmlParser.class
org/xmlpull/
org/xmlpull/v1/
org/xmlpull/v1/XmlPullParser.class
org/xmlpull/v1/XmlPullParserException.class

どういうことだ?
min版でないkxml2-2.3.0.jarにはちゃんとFactoryクラスなど全部はいっているので、
そちらを使ってやれば問題なく使える。

kxml2本店のほうもみてみた。
kxml2 2.3.0のDLページにあるkxml2-min-2.3.0.jarも上記と同じ構成。
XmlPullParserFactoryが入ってない。

仕方ないので、ソース一式落としてみる。
build.xmlがあったので、見てみる。

<target name="build_jar">
  <delete dir="tmpclasses"/>
  <mkdir dir="tmpclasses"/>

  <unzip src="lib/xmlpull_1_1_3_1.jar" dest="tmpclasses" overwrite="true"/>

  <!-- debug="off" -->

  <javac srcdir="src" verbose="true"
    destdir="tmpclasses"
    optimize="true"
    target="1.2"
    source="1.2"
    debuglevel="none"/>

  <mkdir dir="dist"/>

  <jar jarfile="dist/kxml2-${version}.jar" >
    <fileset dir="tmpclasses">
      <include name="**/*.class"/>
      <include name="META-INF/**"/>
    </fileset>
    <fileset dir="src">
      <include name="META-INF/**"/>
    </fileset>
  </jar>

  <jar jarfile="dist/kxml2-min-${version}.jar">
    <fileset dir="tmpclasses">
      <!-- <include name="META-INF/**"/>  -->
      <include name="org/xmlpull/v1/XmlPullParser.class"/>
      <include name="org/xmlpull/v1/XmlPullParserException.class"/>
      <include name="org/kxml2/io/KXmlParser.class"/>
    </fileset>
  </jar>

  <delete dir="tmpclasses"/>
</target>

kxml2はxmlpullというライブラリをベースにしているらしく、
build.xmlでもlib/xmlpull_1_1_3_1.jarを解凍して、
自分のjarに組み込んでいる。
しかし、やはりここでも"org/xmlpull/v1/XmlPullParserFactory"はincludeされない。

<jar jarfile="dist/kxml2-min-${version}.jar">
  <fileset dir="tmpclasses">
    <!-- <include name="META-INF/**"/>  -->
    <include name="org/xmlpull/v1/XmlPullParser.class"/>
    <include name="org/xmlpull/v1/XmlPullParserException.class"/>
    <include name="org/kxml2/io/KXmlParser.class"/>
  </fileset>
</jar>

私の使い方がまずいのか、min版はなにか違うもののためにあるのか、
わからずじまいとなったが、これを見てくれたあなたは通常版を使って快適に過ごしてほしい...。