NAG Technical Report TR 1/04
Calling NAG Library Routines from Java
For someone needing to perform numerical computations, one approach is to create Java classes implementing the required functionality; a group who have made progress in this direction, partly by writing new code and partly by converting pre-existing code from other languages into Java, is the Numerics Working Group of the Java Grande Forum. The JavaNumerics web page  gives much useful information, including discussion of the difficulties of using Java for numerical computation due to constraints imposed by Java as it currently stands.
In this report, we use the alternative approach of calling the NAG Libraries directly from Java, thus evading the job of writing or rewriting code, and everything that that entails in the way of testing. Of course, since we propose to call the NAG Libraries, our application will no longer be portable in the sense that it would have been had it been exclusively written in Java, because now it will rely on the presence of a machine-dependent implementation of a NAG Library at run time. However, it will still be portable in the sense that the NAG Libraries are available on almost all commercially significant machines.
Apart from avoiding the need to first write Java versions of numerical routines, using the NAG Libraries has another advantage. Java has been designed to be portable; a compiled program will run on any machine which has an implementation of the Java Virtual Machine (VM). To accomplish this, the Java compiler does not compile to machine-dependent assembler, as do traditional languages such as C or C++, but to a machine-independent byte code. This byte code then gets interpreted at run time by the VM. Although the Java interpreter is efficient, it is clear that it would be hard for any interpreted program to run as fast as a program compiled to assembler code. For many applications this does not matter; but for applications that perform cpu-intensive operations on large amounts of data, it may be significant. By moving those operations out of Java and into the NAG Libraries, we may therefore hope to cut execution time.
In order to access the NAG Libraries from a Java program, we will
make use of the Java Native Interface.
At compile time, the JNI defines the way that Java data types correspond to C data types – C programs get this information from JNI header files that come with the Java SDK. A tool, javah, that comes with the SDK, aids in creating application-specific header files which aim to eliminate mistakes in communication between Java and C routines.
At run time, the JNI allows the passing of Java objects to the C code, and allows the C code access to Java properties and methods. Thus, for example, the C code can set properties of Java classes, and it is possible to call a Java method from C.
During preparation of this report, we tested code on two machines
Working on UNIX platforms other than Sun/Solaris should be similar to Solaris; the main differences are likely to be in the location of Java include files, and the method of creating a shared object (dynamic library).
A good introduction to the Java Native Interface
can be found at the Sun Microsystems Java Tutorial web site
The interface library is required because when a native method (i.e. function or subroutine) is called from Java, extra arguments are prepended to the argument list of the native routine being called. These extra arguments give the native code access to Java methods and properties, but of course the NAG Libraries were not designed to handle these arguments. Furthermore, the types of the arguments passed from Java do not always correspond exactly to standard C or Fortran types, and so the NAG Libraries cannot use them directly. The interface library must handle these issues, make its own calls to the NAG Library, and then send the results back to Java.
Implementation of a call from Java to a NAG Library is a three-stage process
When the interface library has been built, the Java code
that uses it is still machine-independent even though the
interface library is not. Thus, we need to
build the interface library on all platforms that we are
interested in, but we do not have to edit or rebuild the Java code
that uses it.
|The simplest possible example: we call a function with only one return value – the Y0 (x) Bessel function routine s17acc from the NAG C Library. No special code is required to handle the single return value.|
|We call a function which returns an array of results – the linear equation solver f04arc. Extra code is required to get data from Java to C and results back from C to Java.|
|We call a function which requires a function as one of its arguments – the quadrature routine d01ajc of the NAG C Library. We demonstrate how the C code can call back to a Java method to evaluate the function to be integrated. Also, we will see how the C code can pass results back to Java by modifying Java class properties.|
|This example shows how to call the nonlinear minimization routine e04ucf of the NAG Fortran Library. We demonstrate how the C interface code needs to handle calls to Fortran and deal with callback routines from Fortran to C to Java. We also need to take account of the way Fortran stores two-dimensional arrays.|
If you are interested in calling NAG Fortran routines
from Java, NAG supplies header files 
that can help to make it easier to call NAG Fortran 77 Library
routines from an interface library written in C.