Showing posts with label native. Show all posts
Showing posts with label native. Show all posts

Sunday, May 18, 2014

Learning java native keyword

Today when I study into java code UnixNativeDispatcher.java, the code caught my attention. Snippet below
/**
* int openat(int dfd, const char* path, int oflag, mode_t mode)
*/
static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {
NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
try {
return openat0(dfd, buffer.address(), flags, mode);
} finally {
buffer.release();
}
}
private static native int openat0(int dfd, long pathAddress, int flags, int mode) throws UnixException;

So what happened actually? The static method openat is declared with package modifier which eventually do conversion before native private method openat0 is called. Note that the private method openat0 is actually a non java code execution.

native : Used in method declarations to specify that the method is not implemented in the same Java source file, but rather in another language.

Because it is executed in non java code, if you called native code, the associated method must be implemented in non java language, you can see example how is it done here with hello world example.

But with the native openat0, it came with the precompiled soname file, depending on which jvm you are using, to illustrate using this example. In the directory /usr/lib/jvm/jdk1.7.0_55/jre/lib/amd64/
$ ls /usr/lib/jvm/jdk1.7.0_55/jre/lib/amd64/
fxavcodecplugin-52.so libawt.so libgstreamer-lite.so libjava_crw_demo.so libjdwp.so libjsoundalsa.so libnpjp2.so libt2k.so
fxavcodecplugin-53.so libdcpr.so libhprof.so libjavafx-font.so libjfr.so libjsound.so libnpt.so libunpack.so
fxplugins.so libdeploy.so libinstrument.so libjavafx-iio.so libjfxmedia.so libkcms.so libprism-es2.so libverify.so
headless libdt_socket.so libj2gss.so libjavaplugin_jni.so libjfxwebkit.so libmanagement.so libsaproc.so libzip.so
jli libfontmanager.so libj2pcsc.so libjava.so libjpeg.so libmlib_image.so libsctp.so server
jvm.cfg libglass.so libj2pkcs11.so libjawt.so libjsdt.so libnet.so libsplashscreen.so xawt
libattach.so libgstplugins-lite.so libjaas_unix.so libJdbcOdbc.so libjsig.so libnio.so libsunec.so

As you may notice, there are many precompiled soname files come with jre. To check which soname loaded,
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("nio");
return null;
}});
int flags = init();

hasAtSysCalls = (flags & HAS_AT_SYSCALLS) > 0;
}

obviously libnio.so is loaded, and to read the content of the soname file,
$ objdump -T /usr/lib/jvm/jdk1.7.0_55/jre/lib/amd64/libnio.so | grep openat
000000000000c350 g DF .text 00000000000000ac SUNWprivate_1.1 Java_sun_nio_fs_UnixNativeDispatcher_openat0
$ nm -D /usr/lib/jvm/jdk1.7.0_55/jre/lib/amd64/libnio.so | grep openat0
000000000000c350 T Java_sun_nio_fs_UnixNativeDispatcher_openat0

So that's it, I hope you learned java native keyword too!