- PR -

Java(JNI)でCaboChaを使う方法

1
投稿者投稿内容
むぅいし
会議室デビュー日: 2004/09/17
投稿数: 7
投稿日時: 2004-09-17 15:30
Javaで係り受け解析器CaboChaを動かす方法を探しています。
CaboChaはC言語で動かすことが出来るので、JNIを用いて試みたのですが、
実行途中にエラーが出て止まってしまいます。
主なエラーメッセージは以下の通りです。
An unrecoverable stack overflow has occurred.

An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : EXCEPTION_STACK_OVERFLOW occurred at PC=0x66E57153
Function=cha_tok_is_jisx0208_latin+0xC4C3
Library=C:\JavaHello\cabocha_c\libchasen.dll

JavaでCaboChaを動かす方法を御存知の方、御教授いただければ幸いです。
また、C言語のmain関数(コマンドライン引数を使用)をそのままJNIを使ってJava上で動かす方法でも構いません。

何卒よろしくお願いします。

-----------
Windows XP
Borland C++ コンパイラ5.5
CaboCha-0.51
j2sdk1.4.1_02
------------

unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-09-17 21:21
unibon です。こんにちわ。

引用:

むぅいしさんの書き込み (2004-09-17 15:30) より:
Javaで係り受け解析器CaboChaを動かす方法を探しています。
CaboChaはC言語で動かすことが出来るので、JNIを用いて試みたのですが、
実行途中にエラーが出て止まってしまいます。
主なエラーメッセージは以下の通りです。
An unrecoverable stack overflow has occurred.

An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : EXCEPTION_STACK_OVERFLOW occurred at PC=0x66E57153
Function=cha_tok_is_jisx0208_latin+0xC4C3
Library=C:JavaHellocabocha_clibchasen.dll


CaboCha とかはぜんぜん知らないのですが、エラーメッセージで検索して、リンクをたどっていくと、
http://www.google.co.jp/search?num=50&hl=ja&ie=UTF-8&c2coff=1&q=An+unrecoverable+stack+overflow+has+occurred&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=

http://www.experts-exchange.com/Programming/Programming_Languages/Q_20864382.html

http://forum.java.sun.com/thread.jsp?forum=37&thread=486077&start=0&range=15#2279387
に行き、そのへんのキーワードから、検索すると、たとえばですが、
http://edocs.beasys.co.jp/e-docs/wls/docs70/faq/java.html
みたいなところにたどりつきました。
-ss のオプションあたりで native なスタックサイズを指定できるのかもしれません。
http://java.sun.com/j2se/1.4/ja/docs/ja/tooldocs/win32/java.html
には書いてありませんが、無視はされないような感じもします。
むぅいし
会議室デビュー日: 2004/09/17
投稿数: 7
投稿日時: 2004-09-17 23:26
unibonさん:
ありがとうございます。
まず教えていただいたリンクを読んでみて試せるところは試してみます。
改善できたら報告させていただきます。
むぅいし
会議室デビュー日: 2004/09/17
投稿数: 7
投稿日時: 2004-09-21 15:46
むぅいしです。
unibonさんに教えて頂いたページの方法を試してみました。

http://forum.java.sun.com/thread.jsp?forum=37&thread=418834
を見ると、-Xms -Xms -Xssの組み合わせを使うと良いとかいてありましたので、

C:\JavaHello\cabocha_c>java -ms10m -mx100m -oss2048k -ss2048k ExampleJNI

と全てをデフォルトより数倍大きくして実行してみましたが、以前と変わらないエラーメッセージが出てきました。


いろいろ調べてみた結果、Cのコードの方で、45行目をコンパイルせずに実行すると、
とりあえず、止まらずに最後まで動きました。
以下はCのソースコードです。

#include <jni.h>
#include "ExampleJNI.h"
#include <stdio.h>

#ifdef _WIN32
#include <windows.h>

typedef void* (WINAPI *FPINIT2) (char *);
typedef char* (WINAPI *FPERR) (void*);
typedef char* (WINAPI *FPPARSE) (void*, char*);
typedef void (WINAPI *FPDEL) (void *);

#endif
JNIEXPORT void JNICALL
Java_ExampleJNI_sayHelloWorld (JNIEnv *env, jobject obj){
#ifdef _WIN32
char p[] = "太郎は次郎が持っている本を花子に渡した。";
char* fpparse_temp;
HINSTANCE hLib = LoadLibrary ("libcabocha.dll");

HINSTANCE hLib2 = LoadLibrary ("libchasen.dll");
if (hLib) {
fprintf(stderr, "libchasen loaded.\n");
FreeLibrary(hLib2);
} else {
fprintf(stderr, "Error\n");
}

if (hLib) {
FPINIT2 fpInit2 = (FPINIT2) GetProcAddress(hLib, "cabocha_new2");
FPERR fpErr = (FPERR) GetProcAddress(hLib, "cabocha_strerror");
FPPARSE fpParse = (FPPARSE) GetProcAddress(hLib, "cabocha_sparse_tostr");
FPDEL fpDel = (FPDEL) GetProcAddress(hLib, "cabocha_destroy");

if (fpInit2 && fpErr && fpParse && fpDel) {
void *c = (void *)(*fpInit2)("");
if (!c) {
fprintf (stderr, "Exception %s\n", (*fpErr)(c));
FreeLibrary(hLib);
//return -1;
}

printf ("INPUT: %s\n", p);
     // ↓■■■45行目
printf ("RESULT:\n%s", (char *)(*fpParse)(c, p)); 

(*fpDel)(c);
}
FreeLibrary(hLib);
}
#endif
//return 0;
}


ちなみに、Javaのコードは以下のとおりです。

public class ExampleJNI {
static {
// ライブラリをロードします
System.loadLibrary("example-win32-dll");
}
// ネイティブメソッドを宣言します
//public native void sayHelloWorld(int args, String[] argv);
public native void sayHelloWorld();


public static void main (String[] args) {
ExampleJNI hello = new ExampleJNI();

// メソッドを実行して表示します
hello.sayHelloWorld();

}
}


些細なことでも結構ですので、何かヒントになるようなことがありましたら、
ぜひともご教授ください。

よろしくお願いしたします。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-09-21 16:16
unibon です。こんにちわ。

引用:

むぅいしさんの書き込み (2004-09-21 15:46) より:
     // ↓■■■45行目
printf ("RESULT:n%s", (char *)(*fpParse)(c, p)); 


おそらく、正常にスタックを使って足りなくなっているのではなく、プログラムの間違いでスタック領域を壊してしまっているのだろうと思います。
関数ポインタの使い方が怪しそうですが、ちょっとすぐには分からないです。

もしかしたら、
引用:

むぅいしさんの書き込み (2004-09-17 15:30) より:
また、C言語のmain関数(コマンドライン引数を使用)をそのままJNIを使ってJava上で動かす方法でも構いません。


のほうが良いのかもしれません。
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/lang/Runtime.html#exec(java.lang.String[])
で EXE を起動することはできますが、こんどは情報のやりとりをどうするか(標準入出力を使う等)で悩むかもしれまん。ただ、もちろんスタック関係のエラーは出ようがありませんが。
むぅいし
会議室デビュー日: 2004/09/17
投稿数: 7
投稿日時: 2004-09-21 17:25
むぅいしです。

unibonさん:
早速ご返答頂き、本当にありがとうございます。

教えて頂いたリンクと、
http://www.hellohiro.com/command.htm
を参照してJavaのソースを作り、Javaを実行してみたところ、
EXEを無事に動かすことができました。オプションも問題なく反映されました。

これから自分が作ろうとしているプログラムは、
テキストファイルを入力して、その出力結果をJavaの方で使うという流れなので、
Cのコードを書き換えることで、対応できるような気がしています。

スタックのエラーのほうは、時間の許す限り、もう少し調べてみたいと思います。
きっと、main関数がもともと用意されている場合は、execメソッドで動かす方法が、
一番無難なやり方なのかな、とも思えてきましたが。

また進展がありましたら、ご報告させていただきます。
とんび
常連さん
会議室デビュー日: 2003/07/11
投稿数: 32
投稿日時: 2004-09-21 22:48
引用:

むぅいしさんの書き込み (2004-09-17 15:30) より:
Javaで係り受け解析器CaboChaを動かす方法を探しています。
CaboChaはC言語で動かすことが出来るので、JNIを用いて試みたのですが、
実行途中にエラーが出て止まってしまいます。
主なエラーメッセージは以下の通りです。
An unrecoverable stack overflow has occurred.

An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : EXCEPTION_STACK_OVERFLOW occurred at PC=0x66E57153
Function=cha_tok_is_jisx0208_latin+0xC4C3
Library=C:JavaHellocabocha_clibchasen.dll

JavaでCaboChaを動かす方法を御存知の方、御教授いただければ幸いです。
また、C言語のmain関数(コマンドライン引数を使用)をそのままJNIを使ってJava上で動かす方法でも構いません。

何卒よろしくお願いします。



atmartitでCaboChaの質問が出てくるとは思いませんでした。
知ってるかもしれませんがCaboChaはSwigというCやC++などでできたライブラリをperl/rubyなどのスクリプト言語から呼び出せるにする機構を利用しています。
でこのSwigはJavaにも対応しているはずなのでSwigを使ったほうが楽なのではないでしょうか?
(自分で使ったことはないですがWindowsにも対応してるはず)

ただ、perl/ruby/pythonバインディングがすでにあるのにJavaだけないっていうのはなんか理由があるかもしれないので、
作者にそこらへんのところを聞いといたほうがいいとは思いますが。
むぅいし
会議室デビュー日: 2004/09/17
投稿数: 7
投稿日時: 2004-09-22 16:03
むぅいしです。

とんびさん:
アドバイスありがとうございます。
Swigというものがあることを、昨日CaboChaの作者の方の日記を見て初めて知りました。
なぜJavaのバインディングがないのか、作者の方に理由だけでも聞いてみたいと思います。
理由が分かりましたら、またご報告させていただきます。
1

スキルアップ/キャリアアップ(JOB@IT)