memcached client for javaのインストールにハマる

GNUJavaにはどうもクセがあります.

普通に使われているJavamemcachedへのアクセスクライアント,
http://www.whalin.com/memcached/
をインストールするだけでも時間がかかってしまいました.

ダウンロードして普通にビルドしようとすると,どうしてもエラーが出ます.
クライアントプログラムは,普通にmemcachedに値をセットするこんな感じです.

import com.danga.MemCached.*;
public class Memsetj
{
  public static void main(String[] args)
  {
     String[] serverlist = {args[0]};
     SockIOPool pool = SockIOPool.getInstance();
     pool.setServers(serverlist);
     pool.initialize();
     MemCachedClient memc = new MemCachedClient();
     memc.set(args[1], args[2]);

  }
}

これを普通にビルドしようとするとエラーが出ます.

> gcj --main=Memsetj Memsetj.java --classpath=java_memcached-release_2.0.1.jar
/var/tmp//ccOmnlXe.o(.text+0xb7): In function `void Memsetj::main(JArray<java::lang::String*>*)':
: undefined reference to `com::danga::MemCached::SockIOPool* com::danga::MemCached::SockIOPool::getInstance()'
collect2: ld returned 1 exit status

仕方がないので共有ライブラリにしてリンクしようと...

> gcj -o libjava_memcached java_memcached-release_2.0.1.jar -shared -fPIC 
com/danga/MemCached/test/MemCachedBench.java: In class 'com.danga.MemCached.test.MemCachedBench':
com/danga/MemCached/test/MemCachedBench.java: In method 'com.danga.MemCached.test.MemCachedBench.main(java.lang.String[])':
In file included from com/danga/MemCached/SockIOPool.java:154,
                 from com/danga/MemCached/SockIOPool.java:1521,
                 from com/danga/MemCached/SockIOPool.java:1455,
                 from com/danga/MemCached/SockIOPool.java:140,
                 from com/danga/MemCached/NestedIOException.java:46,
                 from com/danga/MemCached/NativeHandler.java:94,
                 from com/danga/MemCached/MemCachedClient.java:183,
                 from com/danga/MemCached/MemCachedClient.java:2288,
                 from com/danga/MemCached/MemCachedClient.java:2137,
                 from com/danga/MemCached/MCBean.java:1,
                 from com/danga/MemCached/Logger.java:42,
                 from com/danga/MemCached/LineInputStream.java:1,
                 from com/danga/MemCached/ErrorHandler.java:0,
                 from com/danga/MemCached/ContextObjectInputStream.java:49,
                 from com/danga/MemCached/ByteBufArrayInputStream.java:145,
                 from <built-in>:6:
com/danga/MemCached/test/MemCachedBench.java:36: error: cannot find file for class org.apache.log4j.BasicConfigurator
com/danga/MemCached/test/MemCachedBench.java:36: error: class 'org.apache.log4j.BasicConfigurator' has no method named 'configure' matching signature '()V'
com/danga/MemCached/test/MemCachedBench.java:37: error: cannot find file for class org.apache.log4j.Logger
com/danga/MemCached/test/MemCachedBench.java:37: error: class 'org.apache.log4j.Logger' has no method named 'getRootLogger' matching signature '()Lorg/apache/log4j/Logger;'
com/danga/MemCached/test/MemCachedBench.java:37: error: cannot find file for class org.apache.log4j.Level
com/danga/MemCached/test/MemCachedBench.java:37: error: cannot find file for class org.apache.log4j.Level
com/danga/MemCached/test/MemCachedBench.java:37: error: missing field 'OFF' in 'org.apache.log4j.Level'
com/danga/MemCached/test/MemCachedBench.java:37: error: cannot find file for class org.apache.log4j.Logger
com/danga/MemCached/test/MemCachedBench.java:37: error: class 'org.apache.log4j.Logger' has no method named 'setLevel' matching signature '(Lorg/apache/log4j/Level;)V'
com/danga/MemCached/test/MemCachedBench.java:42: confused by earlier errors, bailing out

ちゃんと「using built in Logger:」のlog4jを使わないバージョンを取ってきたのですが,test/以下のプログラムにlog4jを使うコードがあるようです.
仕方がないのでjarを一度分解して,test/以下を消したjarを作ります

> gjar xvf java_memcached-release_2.0.1.jar
  inflated: META-INF/MANIFEST.MF
  created: com/danga/MemCached/test
  inflated: com/danga/MemCached/ByteBufArrayInputStream.class
  inflated: com/danga/MemCached/ContextObjectInputStream.class
  inflated: com/danga/MemCached/ErrorHandler.class
  inflated: com/danga/MemCached/LineInputStream.class
  inflated: com/danga/MemCached/Logger.class
  inflated: com/danga/MemCached/MCBean.class
  inflated: com/danga/MemCached/MemCachedClient$NIOLoader$Connection.class
  inflated: com/danga/MemCached/MemCachedClient$NIOLoader.class
  inflated: com/danga/MemCached/MemCachedClient.class
  inflated: com/danga/MemCached/NativeHandler.class
  inflated: com/danga/MemCached/NestedIOException.class
  inflated: com/danga/MemCached/SockIOPool$1.class
  inflated: com/danga/MemCached/SockIOPool$MaintThread.class
  inflated: com/danga/MemCached/SockIOPool$SockIO.class
  inflated: com/danga/MemCached/SockIOPool.class
  inflated: com/danga/MemCached/test/MemCachedBench.class
  inflated: com/danga/MemCached/test/MemCachedTest$bench.class
  inflated: com/danga/MemCached/test/MemCachedTest.class
  inflated: com/danga/MemCached/test/TestMemcached.class
  inflated: com/danga/MemCached/test/UnitTests$TestClass.class
  inflated: com/danga/MemCached/test/UnitTests.class
> rm -fR com/danga/MemCached/test
> gjar cvf java_memcached-release_2.0.1.jar META-INF com
ignoring entry META-INF/
ignoring entry META-INF/MANIFEST.MF
adding: com/ (in=0) (out=0) (stored 0%)
adding: com/danga/ (in=0) (out=0) (stored 0%)
adding: com/danga/MemCached/ (in=0) (out=0) (stored 0%)
adding: com/danga/MemCached/ByteBufArrayInputStream.class (in=3,273) (out=3,273) (stored 46%)
adding: com/danga/MemCached/ContextObjectInputStream.class (in=1,088) (out=1,088) (stored 51%)
adding: com/danga/MemCached/ErrorHandler.class (in=532) (out=532) (stored 56%)
adding: com/danga/MemCached/LineInputStream.class (in=289) (out=289) (stored 28%)
adding: com/danga/MemCached/Logger.class (in=3,761) (out=3,761) (stored 58%)
adding: com/danga/MemCached/MCBean.class (in=647) (out=647) (stored 47%)
adding: com/danga/MemCached/MemCachedClient$NIOLoader$Connection.class (in=3,987) (out=3,987) (stored 49%)
adding: com/danga/MemCached/MemCachedClient$NIOLoader.class (in=8,210) (out=8,210) (stored 53%)
adding: com/danga/MemCached/MemCachedClient.class (in=29,619) (out=29,619) (stored 58%)
adding: com/danga/MemCached/NativeHandler.class (in=7,070) (out=7,070) (stored 56%)
adding: com/danga/MemCached/NestedIOException.class (in=741) (out=741) (stored 49%)
adding: com/danga/MemCached/SockIOPool$1.class (in=1,216) (out=1,216) (stored 48%)
adding: com/danga/MemCached/SockIOPool$MaintThread.class (in=1,613) (out=1,613) (stored 45%)
adding: com/danga/MemCached/SockIOPool$SockIO.class (in=7,487) (out=7,487) (stored 52%)
adding: com/danga/MemCached/SockIOPool.class (in=25,003) (out=25,003) (stored 54%)

そして再び,共有ライブラリにしようと試みます.

> gcj -o libjava_memcached java_memcached-release_2.0.1.jar -shared -fPIC
>

イケたっぽいです.

> gcj --main=Memsetj Memsetj.java -L. -ljava_memcached -o Memsetj
> env LD_LIBRARY_PATH=. ./Memsetj 127.0.0.1:11211 java_key java_value
com.danga.MemCached.MemCachedClient Sun Jan 31 22:10:38 GMT+09:00 2010 - Storing with native handler...
com.danga.MemCached.MemCachedClient Sun Jan 31 22:10:38 GMT+09:00 2010 - ++++ memcache cmd (result code): set java_key 32 0 10 (STORED)
com.danga.MemCached.MemCachedClient Sun Jan 31 22:10:38 GMT+09:00 2010 - ++++ data successfully stored for key: java_key
> memcat -v --servers=127.0.0.1:11211 abc
key: abc
flags: 20
length: 3
value: 123

じゃあ,値を取る方のプログラムもビルドします.
プログラムはこんな感じです.

import com.danga.MemCached.*;
public class Memgetj
{
  public static void main(String[] args)
  {
     String[] serverlist = {args[0]};
     SockIOPool pool = SockIOPool.getInstance();
     pool.setServers(serverlist);
     pool.initialize();
     MemCachedClient memc = new MemCachedClient();
     memc.setPrimitiveAsString(true);
     System.out.println(memc.get(args[1]));

  }
}

ビルドしてさっきの値をmemcatを使わずに取ってみます.

> gcj --main=Memgetj Memgetj.java -L. -ljava_memcached -o Memgetj
> env LD_LIBRARY_PATH=. ./Memgetj 127.0.0.1:11211 java_key
com.danga.MemCached.MemCachedClient Sun Jan 31 22:11:50 GMT+09:00 2010 - ++++ retrieving object and stuffing into a string.
java_value

Okです.