libgcj システムクラスローダ拡張機能
クラスローダの拡張機能っていうのは,クラスを事前に共有ライブラリにコンパイルしておくと,そのクラスが必要になったときに自動的に共有ライブラリをロードしてその中のクラスを利用してくれるという機能です.
具体的には gnu.pkg.SomeClass クラスが必要になって,それが実行ファイルにリンクされていない場合に,以下のようなファイルを順番に探していきます.
ファイルが見付かればロードしてみてクラスがあればそれを利用します.
libgcj のシステムクラスローダの拡張機能は以下のページに書かれています.
リンクしなくても自動でロードされるのでなかなか便利ですね♪
以下ちょっと実験.
import java.lang.reflect.Method; public class GCJClassLoaderTest { public static void main(String[] args) { try { Class cls = Class.forName("not.exist.ClassName"); Object obj = cls.newInstance(); Method method = cls.getMethod("notFoundMethod", null); method.invoke(obj, null); } catch (Exception e) { e.printStackTrace(); } } }
コンパイルして strace で実行.
% gcj -o GCJClassLoaderTest --main=GCJClassLoaderTest GCJClassLoaderTest.java % strace -o log.txt ./GCJClassLoaderTest java.lang.ClassNotFoundException: not.exist.ClassName not found in [file:/usr/local/java/junit/junit.jar, file:/home/sawai/GNUstep/Library/Libraries/Java, file:/usr/GNUstep/Local/Library/Libraries/Java, file:/usr/GNUstep/System/Library/Libraries/Java/, file:./, core:/] at _ZN4java4lang11VMThrowable16fillInStackTraceEPNS0_9ThrowableE (/usr/lib/libgcj.so.4.0.0) at _ZN4java4lang9Throwable16fillInStackTraceEv (/usr/lib/libgcj.so.4.0.0) ... at main (Unknown Source) at __libc_start_main (/lib/i686/libc-2.3.3.so) at _start (Unknown Source)
not.exist.ClassName な存在しないので当然例外が出て終了します.それは置いておいて得られた log.txt を見てみます.
% grep open log.txt | grep "lib-.*.so" open("/usr/GNUstep/System/Library/Libraries/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/i686/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/home/sawai/GNUstep/Library/Libraries/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/Local/Library/Libraries/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/System/Library/Libraries/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/lib-not-exist-ClassName.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/System/Library/Libraries/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/i686/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/home/sawai/GNUstep/Library/Libraries/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/Local/Library/Libraries/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/System/Library/Libraries/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/lib-not-exist.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/System/Library/Libraries/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/i686/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/home/sawai/GNUstep/Library/Libraries/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/Local/Library/Libraries/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/GNUstep/System/Library/Libraries/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/lib-not.so", O_RDONLY) = -1 ENOENT (No such file or directory)
クラスパスに指定されたディレクトリや /lib /usr/lib 等々からファイルを探しているようです.
libgcj はいろいろとがんばっているんですねぇ.その割には gcj 使われてない気がしますけど…