Thursday, January 28, 2010

Working with Java Native Access [JNA]

There could be a requirement that an application needs to interface with Windows processes. It could be accessing the Dynamic Link Library [DLL], which forms the heart and soul of Windows processes, or accessing some hidden processes.

To satisfy this, we may require to write C/C++ code or use Java Native Interface [JNI] framework. To me, JNI is bit complex and if you think the same, look no further. Now we could use Java Native Access [JNA]. Java Native Access allows the Java programs to access the native shared libraries without using the Java Native Interface [JNI].

Apart from accessing Windows processes, one could use Java Native Access to access the processes of UNIX and Macintosh machines.

Recently I have used Java Native Access in one of the project to create an API such that it will access the base native shared libraries. To start with, I have to identify the native library. So I came to know that there are three basic native libraries which could provide all the major required functions. They are:
<> 
DLL
Description or Use
GDI32.dll
Graphics Device Interface [GDI] functions for device output. For Ex: functions for accessing print devices
Kernel32.dll
Low Level OS functions for memory management
User32.dll
Windows functions, such as the window name, the window file name, etc.
Table 1: Window Native Library Summary

This above table helped me a lot to charter my way to use the required Native library in order get going. Java Native Access [JNA] is beautifully layered architecture API which could be easily accessed to use the Native Library functions.
To get started with Java Native Access, here is simple example to access the kernel32.dll

import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;

public interface Kernel32 extends StdCallLibrary {

Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

long GetCurrentThread();

boolean Beep (int freq, int duration);

}

public class HelloJNA {

System.out.println(Kernel32.INSTANCE.GetCurrentThread());

System.out.println(Kernel32.INSTANCE.Beep(37, 2000));

}

Listing 1.0: Show method implementation of Kernel32 Native Window Library

The listing 1.0, shows the current thread ID implementing the GetCurrentThread() method of the Kernel32. It also shows the implementation of the Beep() method. Upon compiling and executing the above implementation, it will show the current process ID and there will be a beep sound for 2 seconds.

You will also require jna.jar, to be placed in the CLASSPATH to run this above program successfully.

No comments: