Creating Java to native code interfaces with Janet extension

As Java becomes an appropriate environment for high performance computing, the interest arises in combining it with existing code written in other languages. Portable Java interfaces to native code may be developed using the Java Native Interface (JNI). However, as a low-level API it is rather inconvenient to be used directly, thus the higher level tools and techniques are desired. We present Janet – a highly expressive Java language extension and preprocessing tool that enables convenient integration of native code with Java programs.


Introduction
From the small programming language designed for embedded consumerelectronic applications, in few years Java [1] became powerful general-purpose technology used all over the world to solve problems of any kind across different hardware platforms.
Recently, there is a growing interest in application of the Java language in the high performance computing (see e.g., [2,3,4,5].)The reason is that the language is portable (suitable for heterogenous environments), simple (easy to learn), safe (facilitates debugging), secure (enables secure distributed computing), modern (is object oriented, employs automatic memory management and uses exceptions to handle erroneous situations).
As the performance of Java Virtual Machines (VM) continuously increases [3,4] the main issue becomes the lack of scientific libraries designed for use in Java [6].At the same time, there is a good deal of precisely tuned and thoroughly tested scientific libraries written in C, Fortran and other languages.The most appropriate way to make them available in Java is to provide pertinent interfaces for them via the Java Native Interface (JNI) API [7,8].
Unfortunately, as a low level interface JNI is rather inconvenient to be used directly.Several tools which automate interface creation process have been developed [9,10], but such an automatically generated Java to native code interfaces are cumbersome and difficult to use as they do not employ any Java-specific features.They often require manual refinement to achieve Java style and give only limited control over the low-level interface behavior.
In this paper, we present Janet (JAva Native ExTensions), which is the Java language extension.It enables easy, fast, and efficient creation of Java to native code interfaces.
Janet is not an automatic interface generator -it requires the interface to be explicitly described by the programmer.But the description has very natural form of Java source files in which native code is directly embedded.The embedded native code may refer to Java variables, objects and classes, throw and handle Java exceptions, synchronize on Java monitors, access Java strings and arrays using ordinary Java syntax instead of inconvenient and complicated JNI function invocations.

Java Native Interface (JNI)
The JNI [7,8] is a native programming interface which allows Java code running inside a Java Virtual Machine to interoperate with applications and libraries written in other programming languages, such as C, C++, and assembly.One of the most important benefits of the JNI is that it imposes no restrictions on the implementation of the underlying Java VM.
JNI enables to implement Java methods which has been declared as native in Java class definition.Fig. 1 shows interactions between Java application, Java VM, JNI and native code in a typical case when native methods simply serve as an interface between Java application and legacy native library.
The essential feature of JNI is that it enables native code to have the same functionality as pure Java.In particular, it is able to create, inspect and modify objects (including arrays), invoke methods, throw and catch exceptions, synchronize on Java monitors and perform runtime type checking by calling appropriate functions of the JNI API.
The main issue is that the JNI is much closer to the Java VM than Java language itself, so its level of abstraction is rather low which makes the development process long, inconvenient and error prone.Most of the programming mistakes in created interfaces (which are rather easy to make) lead to runtime errors, which are hard to track not only because they may appear only under certain circumstances but also are platform-specific (as are the native languages such as C).The following are the examples of such error-prone situations.
• In order to access Java arrays, native code must invoke special JNI function to lock the array and obtain the pointer to it.When the array is no longer needed, another function must be called to release the array.JNI specification does not define the behavior of a program which fails to release the array.In addition, distinct functions must be used to deal with arrays of different types.The use of improper functions causes runtime errors rather than compile-time errors.This issue is also related to the access to Java strings.

Java interface
Fig. 1: Using native library in a Java application.
be obtained first by using: reference to the class, field name, and its type signature (see [7] for details).There are separate lookup functions for static and instance fields.Also, the accessor functions are different for fields of different types.• Invoking Java methods is even more difficult because method signature includes type signatures of its parameters.There are also different JNI functions for different invocation modes: instance, static and nonvirtual.As a result, when the field type or declared parameter type of a method changes, the interface code becomes invalid and it has to be modified (in contrast, Java code which uses affected field or method only has to be recompiled).• There is no Java-style way to handle exceptions, which may occur in a native methods as a result of JNI calls (for example, when Java methods are invoked).Checking whether exception has been thrown requires explicit query, which is mandatory as the behavior of subsequent JNI calls is undefined when there are a pending exceptions.• Locking and unlocking of Java monitors are two independent operations so frequently the latter is mistakenly omitted at the runtime, especially within exception handling code.
Janet is the Java language extension which enables convenient development of Java to native code interfaces by completely hiding the JNI layer from the user.
Janet source file is similar to ordinary Java source file except that it may contain embedded native code (in terms of native method implementations), and the native code can easily and directly access Java variables as Java code would.Accessing fields, calling methods, synchronization, exception handling, etc.everything what can be done using JNI may be done with Janet using ordinary Java syntax (using backquote "'" characters as an embedded code delimiters).
Currently, the only native language supported by Janet is C, but it will be subject to change in future releases.

Janet
Translator Janet source file Java source file native source file(s) Fig. 2: Janet translation process.
Janet file is transformed by Janet translator into Java and native language source files, as shown on Fig. 2. They conform to JNI-driven Java to native code interface.The code for finding out necessary type signatures, choosing JNI functions to call, loading Java classes, obtaining field and method descriptors, performing array and string lock and release operations, handling and propagating Java exceptions, matching monitor operations, and more -is generated automatically for the user.
The simple example of canonical "Hello World" program using Janet (file HelloWorld.janet) is presented below.class HelloWorld { public native "C" void displayHelloWorld() { printf("Hello world!\n"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld();} } The translation process generates two source files: one for Java class definition and another one for native method implementation.
• File HelloWorld.java: class HelloWorld { static { System.loadLibrary("HelloWorld");} ... As it can be seen, the code for dynamic linking of the library HelloWorld has been generated using the name of the class as the name for the library, because the class appears in default (unnamed) package.If, in contrast, the class appeared in named package, the package name (mangled if necessary, see [7]) would be used instead.This allows that several classes share the library containing implementations of their native methods as long as the classes belong to the same package.function that would leave the block which they appear in.Note, however, that early return is allowed, as Janet guarantees to unlock all monitors and arrays after user-defined code has finished and just before returning the control to the Java VM, so the code below is correct: ... 'synchronized(foo) {' return; '}' ...

Performance results
Janet has been used to develop Java wrappers to the lip runtime library [11] built on top of MPI [12,13,14].The lip library supports both in-and outof-core (OOC) parallel irregular problems [15,16].The generic irregular OOC problem has been written in Java.Its scalability in comparison to C version is presented in Figs. 3 and 4. All computations in the Java test code were performed at the Java side, while the native libraries were provided only as a communication layer and the OOC I/O environment.The amount of computing was controlled with the variable n.It shows that Java can indeed be efficiently applied to large scale parallel scientific computations and its scalability is not worse than that of C language.This paper describes the new approach to creation of Java to native code interfaces.The presented Java language extension called Janet enables simple, fast and efficient development of such interfaces retaining full control over their low-level behavior.We consider providing support for native languages other than C with C++ being the first candidate as it would eliminate problems with the aforementioned unstructural execution flow thanks to the mechanism of object destructors.The next goal is to provide a higher level tool (with graphical user interface) thus enabling the user to graphically design the structure of Java wrappers for a native library.As a result, the tool would generate Janet code which could be further refined by the user.The fully automatic wrapper generator is also under consideration with its output being subject to potential refinement by that GUI tool.

Fig. 3 :Fig. 4 :
Fig. 3: Performance results of the code using the lip library from C and Javan = 100

•
An access to fields of Java objects requires field descriptors which must