(続) mecab で Java Binding
昨日に引き続き。
make test までは通るようになったので、今度は Eclipse + Maven から使えるように環境を準備。昨日のディレクトリで
hyakushiki:mecab-java-0.96 takashi$ jar cvf MeCab-sources.jar org/chasen/mecab/*.java hyakushiki:mecab-java-0.96 takashi$ mvn install:install-file -Dfile=MeCab.jar -DgroupId=org.chasen.mecab -DartifactId=mecab -Dversion=0.96 -Dpackaging=jar hyakushiki:mecab-java-0.96 takashi$ mvn install:install-file -Dfile=MeCab-sources.jar -DgroupId=org.chasen.mecab -DartifactId=mecab -Dversion=0.96 -Dpackaging=jar -Dclassifier=sources
とした後、適当なプロジェクトの pom.xml に
<dependency> <groupId>org.chasen.mecab</groupId> <artifactId>mecab</artifactId> <version>0.96</version> </dependency>
を追加して mvn eclipse:eclipse を実行、と。
後は Eclipse の実行時に環境変数を与えるべく、実行クラスのプロパティの Run/Debug Settings の Environment に DYLD_LIBRARY_PATH を設定することと、JRE System Library をビルド時の環境と同様の Java5 に設定すれば、するりと動きました。
で、CJKAnalyzer を見よう見まねで Mecab で Lucene 2.3 用のアナライザを書いてみて、インデックスを作成してみたり。
public class MecabAnalyzer extends Analyzer { static { try { System.loadLibrary("MeCab"); } catch (UnsatisfiedLinkError e) { throw new RuntimeException(e); } } static final String[] stopWords = {""," ", " ", "て","に","を","は","。","、"}; @Override public TokenStream tokenStream(String fieldName, Reader reader) { TokenStream stream = new MecabTokenizer(reader); return new StopFilter(stream, stopWords); } protected static class MecabTokenizer extends Tokenizer { static Tagger TAGGER; static { TAGGER = new Tagger(); } Reader reader; boolean first = true; int offset = 0; Node node; MecabTokenizer(Reader reader) { this.reader = reader; } @Override public Token next() throws IOException { if (first) { String data = IOUtils.toString(reader); this.node = TAGGER.parseToNode(data); first = false; } else { this.node = node.getNext(); } if (this.node == null) { return null; } int start = offset; int length = node.getLength(); String surface = node.getSurface(); offset += length + 1; String text = new String(surface); return new Token(text, start, start + length); } @Override public void close() throws IOException { IOUtils.closeQuietly(reader); } } }
また、Tagger は Stream をくるくる回すのではなく、一括で文字列を解析するようなので、一旦 IOUtils で reader を読み切ってしまってますが、大きなデータだと、メモリを食ってしまうかも。