読者です 読者をやめる 読者になる 読者になる

TokyoCabinet + JavaAPIでの不具合?

OS:ubuntu 8.04(32bit)
tokyocabinet-1.4.44
tokyocabinet-java:1.23

gcc -v
Using built-in specs.
Target: i486-linux-gnu
コンフィグオプション: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
スレッドモデル: posix
gcc バージョン 4.1.3 20080308 (prerelease) (Ubuntu 4.1.2-21ubuntu1)


以下のコードを実行すると

bdb = new BDB();
if(!bdb.open("casket.tcb", BDB.OWRITER | BDB.OCREAT)) {
	Assert.fail();
}
bdb.put("watanabe", "yusaku");
bdb.put("watanabe0", "yusaku0");
bdb.put("watanabe01", "yusaku01");
List<String> rslt = bdb.range("yusaku", true, null, true, -1);

JVMがクラッシュします。

BDB.javaのrangeメソッドは

  public List range(String bkey, boolean binc, String ekey, boolean einc, int max){
    List keys = range(bkey.getBytes(), binc, ekey.getBytes(), einc, max);
    List skeys = new ArrayList();
    Iterator it = keys.iterator();
    while(it.hasNext()){
      byte[] key = (byte[])it.next();
      skeys.add(Util.otos(key));
    }
    return skeys;
  }

となっていたので、getBytes()でぬるぽかと思って、試しに

  public List range(String bkey, boolean binc, String ekey, boolean einc, int max){
    List keys = range(null, binc, null, einc, max);
    List skeys = new ArrayList();
    Iterator it = keys.iterator();
    while(it.hasNext()){
      byte[] key = (byte[])it.next();
      skeys.add(Util.otos(key));
    }
    return skeys;
  }

とかやってみたけど変わらず。



JNIは使ったことないので、原因がよくわからんのですがnullをうまく引数として渡せてないっぽい。
とりあえずtokyocabinet-java-1.23/bdb.c:512行目
if(ekey){

if((*env)->GetArrayLength(env, ekey) > 0){
に修正したらうまく動いた。

これでいいんだろうか