報國挺身日記 このページをアンテナに追加 RSSフィード

2009/10/17

[] libnet.so 02:14

10/08の続き。

作成したnative libraryはロードできてアプリケーションも動作するようになったが、何故か起動時にエラーになる環境もある。

エラーログを見ると、libnet.soをロードしているところでSEGVが発生していた。

libnet.soは、java.net.*のnative libraryで、今回作成したnative libraryからリンクしている。

 $(CC) -shared $(NATIVE_OBJS) -L$(JDK_HOME)/jre/lib/i386 -lnet -ljava -o $@

JDKのソースを読んで、SEGVしている場所がわかった。

$JDK16_SOURCE/j2se/src/solaris/native/java/net/net_util_md.cの中にあるinitLocalIfs()関数は、二回呼び出されると、二度目に呼んだとき必ずSEGVが起きる。(Linuxの場合のみ)

この関数はnative libraryをロードしたときに自動的に呼び出されるJNI_OnLoad()の中から呼ばれるようになっている。Javaの起動時点で一度呼び出され、その後、作成したnative libraryをロードしたときに、リンクしているlibnet.soが再度ロードされるのでSEGVするようになってしまった。

libnet.soはJava Native Interfaceの範囲外だから、リンクして使用することが間違っていると言われればそれまでだが、これを使用しないでネットワーク関係のnative libraryを実装するのも難しい。

簡単な対処方法は見つかった。initLocalIfs()の最初のところで以下のように/proc/net/if_inet6をopenできなければ処理を実行せずにreturnしているので、OSレベルでIPv6を無効にすればSEGVしなくなる筈。

    if ((f = fopen("/proc/net/if_inet6", "r")) == NULL) {
	return ;
    }

2009/10/08

[] sun.boot.library.path 22:55

Javaの標準パッケージの中からしかアクセスできないクラスを参照する必要があったので、参照したいpackageの中に新規のクラスを追加することで対処した。その場合、そのクラスはbootclassに指定しなければならなくなる。

bootclassにすると、そのクラスからロードしているnative libraryを見つけることが出来なくてエラーになった。LD_LIBRARY_PATH, java.library.pathで指定しても効果がない。どうすればよいのかわからなくて結局、$JDK_HOME/jre/lib/i386の中にnative libraryを放り込んで済ませていた。

今日、正しい方法がわかった。bootclassの場合にはjava.library.pathではなくsun.boot.library.pathプロパティで指定すれば良い。

java -Dsun.boot.library.path=.  -Xbootclasspath/a:xxx.jar

2007/02/27

[] Appletでのmodal dialog 21:58

Java Swingを使って書いたアプリケーションをアプレットに書き換えているときに、modal dialogをどうやって作るのかが解らなくて困った。

new JDialog(frame, true);

に渡すためのFrameがアプレットにはない。

結局、modal dialogを出すためだけのJFrameオブジェクトを生成して、それを渡すことで解決できた。もっと正式な方法があるような気がするが。

2006/05/14 次元の呪い

[][] Seasar Conference 2006 Spring 21:58

Seasar Conference 2006 Springに行って来た。「DI入門」のセッションで、「設計と実装の分離」と説明していたが、あれは普通「仕様と実装の分離」というのではないだろうか?「設計と実装の分離」だと、全然違う意味の話になってしまう。

2006/04/12 酸性化する太平洋

[][] Echo2 22:55

2.1.0beta1が出た。