SudachiというJavaの形態素解析ツールを使いたいと思います。Sudachiは辞書が別配布になっているため、Sudachi本体と辞書を1つのjarファイルにまとめたのですが、mavenに不慣れでどのように設定していいかで困っています。

やりたいこと

辞書込みのjarファイルをartifactoryに設置して、別プロジェクトからjarファイルを読み込むだけでSudachiによる形態素解析ができるようにしたい。

なぜこのようなことをするかというと、これも知識不足でお恥ずかしいのですが、MapReduceプロセスでSudachi辞書がロードできずに止まってしまいます。Kuromojiでは動いているため、同様に1つのjarにまとめれば問題が起きないと期待しています。

関連リンク

やったこと

Kuromojiのpom.xmlを参考にしました。kuromoji本体ではなく、次のビルドスクリプトでneologdを使ったkuromojiを参考にしています。

https://github.com/kazuhira-r/kuromoji-with-mecab-neologd-buildscript/blob/master/build-atilika-kuromoji-with-mecab-ipadic-neologd.sh

pom.xml

あまり理解せずに書いていて恐縮ですが、次のようなpom.xmlを作成しました。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xxx.sudachi</groupId>
    <artifactId>sudachi</artifactId>
    <version>0.3.0-20190927</version>

    <name>Sudachi my version</name>

    <packaging>jar</packaging>

    <properties>
        <sudachi.dict>sudachi-dictionary-20190927</sudachi.dict>
        <sudachi.dict.file>${sudachi.dict}-full.zip</sudachi.dict.file>
        <sudachi.dict.url>https://object-storage.tyo2.conoha.io/v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/${sudachi.dict.file}</sudachi.dict.url>
        <sudachi.dict.dir>${project.basedir}/dictionary/mecab-ipadic-2.7.0-20070801</sudachi.dict.dir>
        <sudachi.dict.targetdir>${project.basedir}/src/main/resources/com/atilika/kuromoji/ipadic</sudachi.dict.targetdir>
    </properties>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <id>copy-license-resources</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.outputDirectory}/META-INF</outputDirectory>
                            <resources>
                                <resource>
                                    <!-- Becomes top level directory. Is there a better way to do this? -->
                                    <directory>${project.basedir}/dictionary</directory>
                                    <filtering>false</filtering>
                                    <includes>
                                        <include>${sudachi.dict}</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>compile-dictionary</id>
            <activation>
                <property>
                    <name>!skipCompileDictionary</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <version>1.6</version>
                        <executions>
                            <execution>
                                <id>download-dictionary</id>
                                <phase>generate-resources</phase>
                                <configuration>
                                    <target unless="skipDownloadDictionary">
                                        <echo message="Downloading dictionary"/>
                                        <delete dir="dictionary"/>
                                        <mkdir dir="dictionary"/>
                                        <get src="${sudachi.dict.url}"
                                             dest="dictionary/${sudachi.dict.file}"/>
                                        <unzip src="dictionary/${sudachi.dict.file}"
                                               dest="dictionary"/>
                                    </target>
                                </configuration>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                </plugins>
            </build>
        </profile>
    </profiles>

    <dependencies>
        <dependency>
            <groupId>com.worksap.nlp</groupId>
            <artifactId>sudachi</artifactId>
            <version>0.3.0</version>
        </dependency>
    </dependencies>
</project>

計画はあるがまだ行っていないこと

  • sudachi.json をプロジェクトに追加していない
  • コードはまだ書いていない(jarファイル内のsudachi.jsonを読み、辞書の初期化をするコードが必要)

質問 (2019年10月15日追記)

上記のコピペpom.xmlの問題点と修正すべき点があればご指摘ください。上記の通り目的は1つのjarファイルを配置するだけで辞書の置き場などの設定抜きに文字列分割ができることです。

追記2 (2019年10月15日追記)

「Sudachiの辞書がMapReduceで読めない」こととpom.xmlの設定がわからないことは別問題です。

参考:Getting file resource from Jar in Hadoop
https://stackoverflow.com/questions/43100956/getting-file-resource-from-jar-in-hadoop

MapReduceでSudachiが使えない問題の回避方法は複数あると思います。上記のリンク先で言及されているように、Distributed cacheを使う手もあるでしょうが、今回はSudachi.jarを作ることで回避したいと思っています。Kuromojiは辞書とプログラムが1つのjarに入っていて、これは問題なくMapReduceから使うことができますし、他の細かい問題も同時に解決するからです。

繰り返しになりますが、質問の趣旨は

  • SudachiとSudachi辞書を1つのjarファイルに入れること
  • 他のプロジェクトから、次のように(これはkuromoji)jarファイルを参照できること
  • String tokenized = Sudachi.tokenize("今日は水曜日です"); のようなインタフェースをjarファイル内に実装すること。
        <dependency>
            <groupId>自分のリポジトリ.kuromoji</groupId>
            <artifactId>kuromoji-unidic</artifactId>
            <version>0.9.0</version>
        </dependency>

よろしくお願いします。