形態素解析ライブラリSenのエラーと原因究明方法

Java形態素解析ライブラリSenを使ってプログラムを書いていたのですが、実行環境を変えると急に動かなくなってしまいました。メモ代わりに対処法を残しておきます。

エラーメッセージとその原因など

私の場合、発生したエラーメッセージは

java.lang.IllegalArgumentException: unknown protocol: c

java.lang.IllegalArgumentException: Tokenizer Class: net.java.sen.ja.JapaneseTokenizer is invalid.

などです。例外が発生しているのはライブラリの奥深く、エラーメッセージも意味不明のため、どうしていいのかわかりません。


こんなときに頼りになるのがGoogle先生です!しかし、そもそも形態素解析Javaでやっている人の母数が小さいためか、Google先生もあまりこの問題には詳しくないようです。

それでも出てきた情報をまとめると次のようになります。

  • System.setProperty("sen.home", senHome)を忘れずに(senHomeはSenのディレクトリへのパス)。
  • VMのメモリ不足が原因の場合がある。
    • 実行時のオプションで-Xms(初期ヒープサイズ)、-Xmx(最大ヒープサイズ)を指定(例:最大ヒープサイズを256MBにするには、-Xmx256mを指定)
  • Program Filesのような、スペースを含むパスを指定するとエラーになるおそれあり(移行前のマシンでは動いたのに移行後はエラー発生)
    • スペースを含まないパスで指定できる場所にSenをディレクトリごと移動
  • SenはIllegalArgumentExceptionを投げまくる(別の例外をcatchした上で、IllegalArgumentExceptionを投げているケースが多い)
    • IllegalArgumentExceptionが投げられる前に発生した例外の中身を見ることができれば原因究明できる可能性あり

原因究明方法

上記の最後の項についてですが、Senにはソースがついている(SEN_HOMEのsrc/javaの中)ので、sen.jarを使わずに、そのソースのプログラムを書き換えて使うことで、本当の原因となっている例外のメッセージやスタックトレースを表示できます。


例えば、

java.lang.IllegalArgumentException: unknown protocol: c
at net.java.sen.StringTagger.readConfig(StringTagger.java:310)
at net.java.sen.StringTagger.init(StringTagger.java:145)
at net.java.sen.StringTagger.(StringTagger.java:95)
at net.java.sen.StringTagger.getInstance(StringTagger.java:13
(以下省略)

というエラーメッセージの場合は、StringTagger.javaの310行目でIllegalArgumentExceptionがスローされています。この部分を見てみると、

        } catch (IOException e) {
            throw new IllegalArgumentException(e.getMessage());
        }

となっており、実はIOExceptionが発生していることがわかります。そこで、このIOExceptionのエラーメッセージを見るために

        } catch (IOException e) {
            e.printStackTrace();
            throw new IllegalArgumentException(e.getMessage());
        }

のようにソースを書き換えてしまいます。


このようにして、意味不明のエラーメッセージの裏側で、実は何が起こっているのかを調べることができます。

(ちなみに、私の場合はパス中の「Program Files」のスペースがよくなかったようです。移行前の環境では(Windows XP同士の移行なのに)動いていたので謎です)

参考サイト

調べた中で特に役立ったものを挙げておきます。特に、原因究明の方法は二つ目のブログのやり方そのままです。