tohokuaikiのチラシの裏

技術的ネタとか。

ConfluenceのPlugin作成でApache XMLRPCを使おうとしたらSAXParserでエラー出た件

プラグインでXMLRPCできるようにしたい

ということで、pom.xmlapache.xmlrpcを追加

        <dependency>
            <groupId>org.apache.xmlrpc</groupId>
            <artifactId>xmlrpc-client</artifactId>
            <version>3.1.3</version>
        </dependency>

あんまり久しぶりだったので、NetBeansから追加した際に<scope>jar</scope>が入っててそのままにしたらコンパイルは通るんだけど、実際に動作させるとNoClassDefFoundErrorが出てしまって悩んだのはいい経験。

これで難なく使えるはず・・・が・・・

コンパイル・インストール問題なくいくのだけど、動作させると

Cause
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
caused by: java.lang.ExceptionInInitializerError
    at org.apache.xmlrpc.client.XmlRpcStreamTransport.newXMLReader(XmlRpcStreamTransport.java:176)
caused by: java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory
    at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)

ってエラーが。

あれー、SAXParserで何か引っかかっている・・・・・。

んん~、って思ってググったらAtlassian Answersにバッチリな回答が。
I'm blocked, help: cannot be cast to javax.xml.parsers.SAXParserFactory - Atlassian Answers

要約すると、

  1. apache.xmlrpcもSAX使ってる(atlas-mvn dependency:tree すると xml-apis:xml-apis:jar:1.3.02:compile がapache.xmlrpcにぶら下がってるのが分かる)
  2. だけど、SAXは既にclasspath内にJarで存在している
  3. XMLパーサのFactoryは実行時に実装を決めるので、2つ実装が見えていると問題が発生する
  4. ということで、依存性を追加する際に「xml-apis」は追加しないようにすればよい

要するに

pom.xmlに加える際に

        <dependency>
            <groupId>org.apache.xmlrpc</groupId>
            <artifactId>xmlrpc-client</artifactId>
            <version>3.1.3</version>
            <exclusions>
                <exclusion>
                    <artifactId>xml-apis</artifactId>
                    <groupId>xml-apis</groupId>
                </exclusion>
            </exclusions>
        </dependency>

って除外すればいいですよということ。