Java Native Interface
Encyclopedia
The Java Native Interface
(JNI) is a programming framework
that enables Java
code running in a Java Virtual Machine
(JVM) to call and to be called by native applications (programs specific to a hardware
and operating system
platform) and libraries written in other languages such as C
, C++
and assembly
.
library
does not support the platform-specific features or program library. It is also used to modify an existing application—written in another programming language—to be accessible to Java applications. Many of the standard library classes depend on JNI to provide functionality to the developer and the user, e.g. file I/O and sound capabilities. Including performance- and platform-sensitive API implementations in the standard library allows all Java applications to access this functionality in a safe and platform-independent manner.
The JNI framework lets a native method use Java objects
in the same way that Java code uses these objects. A native method can create Java objects and then inspect and use these objects to perform its tasks. A native method can also inspect and use objects created by Java application code.
JNI is sometimes referred to as the "escape hatch" for Java developers because it enables them to add functionality to their Java application that the standard Java APIs cannot otherwise provide. It can be used to interface with code written in other languages, such as C and C++. It is also used for time-critical calculations or operations like solving complicated mathematical equations, because native code may be faster than JVM code.
The
For example, the following converts a Java string to a native string:
Note that C++ JNI code is syntactically slightly cleaner than C JNI code because like Java, C++ uses object method invocation semantics. That means that in C, the
Native data type
s can be mapped to/from Java data types. For compound types such as objects, arrays and string
s the native code must explicitly convert the data by calling methods in the
In addition, the signature "L fully-qualified-class ;" would mean the class uniquely specified by that name; e.g., the signature "Ljava/lang/String;" refers to the class java.lang.String. Also, prefixing
Here, these types are interchangeable. You can use
However, mapping between Java Strings and arrays to native strings and arrays is different. If you use a
This is similar with Java arrays, as illustrated in the example below that takes the sum of all the elements in an array.
Of course, there is much more to it than this. Look for links below for more information.
To attach to the current thread and get a JNI interface pointer:
JNIEnv *env;
(*g_vm)->AttachCurrentThread (g_vm, (void **) &env, NULL);
To detach from the current thread:
(*g_vm)->DetachCurrentThread (g_vm);
. The process is almost the same, with just a few changes. The Java AWT Native Interface is only available since J2SE
1.3.
, without even going through a C
bridge. Accessing Java applications from assembly is also possible in the same way.
) had a similar mechanism for calling native Windows code from Java, called the Raw Native Interface (RNI). However, following the Sun - Microsoft litigation about this implementation, Visual J++
is no longer maintained.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
javac HelloWorld.java
javah HelloWorld
gcc -shared libHelloWorld.c -o libHelloWorld.so
java HelloWorld
HelloWorld.java
class HelloWorld
{
private native void print;
public static void main(String[] args)
{
new HelloWorld.print;
}
static{
System.loadLibrary("HelloWorld");
}
}
HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
/* Header for class HelloWorld */
extern "C" {
/*
* Class: HelloWorld
* Method: print
* Signature: V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
}
libHelloWorld.c
#include "jni.h"
#include
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
chmod 700 make.sh
./make.sh
Java Native Interface
The Java Native Interface is a programming framework that enables Java code running in a Java Virtual Machine to call and to be called by native applications and libraries written in other languages such as C, C++ and assembly.-Purpose and features:JNI enables one to write native methods to...
(JNI) is a programming framework
Software framework
In computer programming, a software framework is an abstraction in which software providing generic functionality can be selectively changed by user code, thus providing application specific software...
that enables Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
code running in a Java Virtual Machine
Java Virtual Machine
A Java virtual machine is a virtual machine capable of executing Java bytecode. It is the code execution component of the Java software platform. Sun Microsystems stated that there are over 4.5 billion JVM-enabled devices.-Overview:...
(JVM) to call and to be called by native applications (programs specific to a hardware
Hardware
Hardware is a general term for equipment such as keys, locks, hinges, latches, handles, wire, chains, plumbing supplies, tools, utensils, cutlery and machine parts. Household hardware is typically sold in hardware stores....
and operating system
Operating system
An operating system is a set of programs that manage computer hardware resources and provide common services for application software. The operating system is the most important type of system software in a computer system...
platform) and libraries written in other languages such as C
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
, C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
and assembly
Assembly language
An assembly language is a low-level programming language for computers, microprocessors, microcontrollers, and other programmable devices. It implements a symbolic representation of the machine codes and other constants needed to program a given CPU architecture...
.
Purpose and features
JNI enables one to write native methods to handle situations when an application cannot be written entirely in the Java programming language, e.g. when the standard Java classClass (computer science)
In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior...
library
Library (computer science)
In computer science, a library is a collection of resources used to develop software. These may include pre-written code and subroutines, classes, values or type specifications....
does not support the platform-specific features or program library. It is also used to modify an existing application—written in another programming language—to be accessible to Java applications. Many of the standard library classes depend on JNI to provide functionality to the developer and the user, e.g. file I/O and sound capabilities. Including performance- and platform-sensitive API implementations in the standard library allows all Java applications to access this functionality in a safe and platform-independent manner.
The JNI framework lets a native method use Java objects
Object (computer science)
In computer science, an object is any entity that can be manipulated by the commands of a programming language, such as a value, variable, function, or data structure...
in the same way that Java code uses these objects. A native method can create Java objects and then inspect and use these objects to perform its tasks. A native method can also inspect and use objects created by Java application code.
JNI is sometimes referred to as the "escape hatch" for Java developers because it enables them to add functionality to their Java application that the standard Java APIs cannot otherwise provide. It can be used to interface with code written in other languages, such as C and C++. It is also used for time-critical calculations or operations like solving complicated mathematical equations, because native code may be faster than JVM code.
Pitfalls
- subtle errors in the use of JNI can destabilize the entire JVM in ways that are very difficult to reproduce and debug.
- only applications and signed applets can invoke JNI.
- an application that relies on JNI loses the platform portability Java offers (a workaround is to write a separate implementation of JNI code for each platform and have Java detect the operating system and load the correct one at runtime).
- the JNI framework does not provide any automatic garbage collection for non-JVM memory resources allocated by code executing on the native side. Consequently, native side code (such as assembly languageAssembly languageAn assembly language is a low-level programming language for computers, microprocessors, microcontrollers, and other programmable devices. It implements a symbolic representation of the machine codes and other constants needed to program a given CPU architecture...
) must assume the responsibility for explicitly releasing any such memory resources that it itself acquires. - error checking is a must or it has the potential to crash the JNI side and the JVM.
- on Linux and Solaris platforms, if the native code registers itself as a signal handler, it could intercept signals intended for the JVM. Signal chaining should be used to allow native code to better interoperate with JVM.
- on Windows platforms, Structured Exception Handling (SEH) may be employed to wrap native code in SEH try/catch blocks so as to capture machine (CPU/FPU) generated software interrupts (such as NULL pointer access violations and divide-by-zero operations), and to handle these situations before the interrupt is propagated back up into the JVM (i.e. Java side code), in all likelihood resulting in an unhandled exception.
- The encoding used for the NewStringUTF, GetStringUTFLength, GetStringUTFChars, ReleaseStringUTFChars, GetStringUTFRegion functions is not standard UTF-8, but modified UTF-8. The null character (U+0000) and codepoints greater than or equal to U+10000 are encoded differently in modified UTF-8. Many programs actually use these functions incorrectly and treat the UTF-8 strings returned or passed into the functions as standard UTF-8 strings instead of modified UTF-8 strings. Programs should use the NewString, GetStringLength, GetStringChars, ReleaseStringChars, GetStringRegion, GetStringCritical, and ReleaseStringCritical functions, which use UTF-16LE encoding on little-endian architectures and UTF-16BE on big-endian architectures, and then use a UTF-16 to standard UTF-8 conversion routine.
How the JNI works
In the JNI framework, native functions are implemented in separate .c or .cpp files. (C++ provides a slightly simpler interface with JNI.) When the JVM invokes the function, it passes aJNIEnv
pointer, a jobject
pointer, and any Java arguments declared by the Java method. A JNI function may look like this:The
env
pointer is a structure that contains the interface to the JVM. It includes all of the functions necessary to interact with the JVM and to work with Java objects. Example JNI functions are converting native arrays to/from Java arrays, converting native strings to/from Java strings, instantiating objects, throwing exceptions, etc. Basically, anything that Java code can do can be done using JNIEnv
, albeit with considerably less ease.For example, the following converts a Java string to a native string:
Note that C++ JNI code is syntactically slightly cleaner than C JNI code because like Java, C++ uses object method invocation semantics. That means that in C, the
env
parameter is dereferenced using (*env)->
and env
has to be explicitly passed to JNIEnv
methods. In C++, the env
parameter is dereferenced using env->
and the env
parameter is implicitly passed as part of the object method invocation semantics.Native data type
Data type
In computer programming, a data type is a classification identifying one of various types of data, such as floating-point, integer, or Boolean, that determines the possible values for that type; the operations that can be done on values of that type; the meaning of the data; and the way values of...
s can be mapped to/from Java data types. For compound types such as objects, arrays and string
String (computer science)
In formal languages, which are used in mathematical logic and theoretical computer science, a string is a finite sequence of symbols that are chosen from a set or alphabet....
s the native code must explicitly convert the data by calling methods in the
JNIEnv
.Mapping types
The following table shows the mapping of types between Java and native code.Native Type | Java Language Type | Description | Type signature |
---|---|---|---|
unsigned char | jboolean | unsigned 8 bits | Z |
signed char | jbyte | signed 8 bits | B |
unsigned short | jchar | unsigned 16 bits | C |
short | jshort | signed 16 bits | S |
long | jint | signed 32 bits | I |
long long __int64 |
jlong | signed 64 bits | J |
float | jfloat | 32 bits | F |
double | jdouble | 64 bits | D |
In addition, the signature "L fully-qualified-class ;" would mean the class uniquely specified by that name; e.g., the signature "Ljava/lang/String;" refers to the class java.lang.String. Also, prefixing
[
to the signature makes the array of that type; for example, [I
means the int array type.Here, these types are interchangeable. You can use
jint
where you normally use an int
, and vice-versa, without any typecasting required.However, mapping between Java Strings and arrays to native strings and arrays is different. If you use a
jstring
in where a char *
would be, your code could crash the JVM.This is similar with Java arrays, as illustrated in the example below that takes the sum of all the elements in an array.
Of course, there is much more to it than this. Look for links below for more information.
JNIEnv*
A JNI interface pointer (JNIEnv*) is passed as an argument for each native function mapped to a Java method, allowing for interaction with the JNI environment within the native method. This JNI interface pointer can be stored, but remains valid only in the current thread. Other threads must first call AttachCurrentThread to attach themselves to the VM and obtain a JNI interface pointer. Once attached, a native thread works like a regular Java thread running within a native method. The native thread remains attached to the VM until it calls DetachCurrentThread to detach itself.To attach to the current thread and get a JNI interface pointer:
JNIEnv *env;
(*g_vm)->AttachCurrentThread (g_vm, (void **) &env, NULL);
To detach from the current thread:
(*g_vm)->DetachCurrentThread (g_vm);
Native AWT painting
Not only can native code interface with Java, it can also draw on a Java , which is possible with the Java AWT Native InterfaceJava AWT Native Interface
Java AWT Native Interface is an interface for the Java programming language that enables rendering libraries compiled to native code to draw directly to a Java Abstract Window Toolkit object drawing surface....
. The process is almost the same, with just a few changes. The Java AWT Native Interface is only available since J2SE
Java Platform, Standard Edition
Java Platform, Standard Edition or Java SE is a widely used platform for programming in the Java language. It is the Java Platform used to deploy portable applications for general use...
1.3.
Access to assembly code
JNI also allows direct access to assembly codeAssembly language
An assembly language is a low-level programming language for computers, microprocessors, microcontrollers, and other programmable devices. It implements a symbolic representation of the machine codes and other constants needed to program a given CPU architecture...
, without even going through a C
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
bridge. Accessing Java applications from assembly is also possible in the same way.
Microsoft's RNI
Microsoft's proprietary implementation of a Java Virtual Machine (Visual J++Visual J++
Visual J++ was Microsoft's specific implementation of Java. Syntax, keywords, and grammatical conventions were the same as Java's. Microsoft discontinued support of J++ in January 2004, replacing it to a certain extent with J# and C#....
) had a similar mechanism for calling native Windows code from Java, called the Raw Native Interface (RNI). However, following the Sun - Microsoft litigation about this implementation, Visual J++
Visual J++
Visual J++ was Microsoft's specific implementation of Java. Syntax, keywords, and grammatical conventions were the same as Java's. Microsoft discontinued support of J++ in January 2004, replacing it to a certain extent with J# and C#....
is no longer maintained.
HelloWorld
make.sh- !/bin/sh
- openbsd 4.9
- gcc 4.2.1
- openjdk 1.7.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
javac HelloWorld.java
javah HelloWorld
gcc -shared libHelloWorld.c -o libHelloWorld.so
java HelloWorld
HelloWorld.java
class HelloWorld
{
private native void print;
public static void main(String[] args)
{
new HelloWorld.print;
}
static{
System.loadLibrary("HelloWorld");
}
}
HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
- include
/* Header for class HelloWorld */
- ifndef _Included_HelloWorld
- define _Included_HelloWorld
- ifdef __cplusplus
extern "C" {
- endif
/*
* Class: HelloWorld
* Method: print
* Signature: V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
- ifdef __cplusplus
}
- endif
- endif
libHelloWorld.c
#include "jni.h"
#include
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
chmod 700 make.sh
./make.sh
See also
- Java AWT Native InterfaceJava AWT Native InterfaceJava AWT Native Interface is an interface for the Java programming language that enables rendering libraries compiled to native code to draw directly to a Java Abstract Window Toolkit object drawing surface....
- GluegenGluegenGlueGen is a Java tool which automatically generates the Java and Java Native Interface code needed to call C libraries from Java code. It reads in ANSI C header files and GlueGen configuration files, and emits C code...
, a Java tool which automatically generates the Java and JNI code necessary to call C libraries from Java code. - P/InvokePlatform Invocation ServicesPlatform Invocation Services, commonly referred to as P/Invoke, is a feature of Common Language Infrastructure implementations, like Microsoft's Common Language Runtime, that enables managed code to call native code.-Explicit:...
, the .NET Framework.NET FrameworkThe .NET Framework is a software framework that runs primarily on Microsoft Windows. It includes a large library and supports several programming languages which allows language interoperability...
equivalent of JNI. - SWIGSWIGSWIG is an open source software tool used to connect computer programs or libraries written in C or C++ with scripting languages such as Lua, Perl, PHP, Python, R, Ruby, Tcl, and other languages like C#, Java, Modula-3, Objective Caml, Octave, and Scheme...
is a multilanguage interface generator for C and C++ libraries that can generate JNI code - Java Native AccessJava Native AccessJava Native Access provides Java programs easy access to native shared libraries without using the Java Native Interface. JNA's design aims to provide native access in a natural way with a minimum of effort...
provides Java programs easy access to native shared libraries without writing boiler plate code - JNI.pas JNI interface to Pascal
External links
- Oracle's JNI page for Java 6, including the JNI Specification
- Java Native Interface: Programmer's Guide and Specification - Book, copyright 2002.
- Best practices for using the Java Native Interface
- JNI Complete tutorial with examples
- GNU CNI Tutorial
- Multi-platform JNI Tutorial at Think-Techie.com
- A JNI Tutorial at CodeProject.com (Microsoft specific)
- JNI Tutorial at CodeToad.com
- Larger JNI example from Sun
- JNI video tutorial with Eclipse and Visual Studio
- JNI in XCode from Apple
- Exception handling in JNI
- HawtJNI Simplifies creating JNI libraries by code generating the JNI implementations using declarative annotations placed on your Java code.
- Jace is a toolkit designed to make it easy to write JNI-based programs
- JNIWrapper provides simplified access to native code from Java applications without using Java Native Interface.
- Java to Native Interface LGPL library to call native functions from Java
- Java Native Access Access to native libraries from Java without JNI
- NLink Another library for access to native libraries without JNI
- NativeCall – call native methods from Java without JNI Library to access native code without JNI
- JNIEasy Transparent Native Programming for C/C++, pure Java alternative to JNI using POJOS and JDO/JPA development style
- jni4net bridge between Java and .NET (intraprocess, fast, object oriented, open-source)
- Object-Oriented JNI Advanced Add-in for VC6 Object-Oriented JNI with a number of helpers that includes the standard JNI SDK for regular C++ (Commercial)
- Object-Oriented JNI for .NET1.1 (low-level) Object-Oriented JNI with a number of helpers that includes the standard JNI SDK for C#, Managed C++, VB#, J# (Commercial)
- Object-Oriented JNI for .NET2.0 (low-level) Object-Oriented JNI with a number of helpers that includes the standard JNI SDK for C#, Managed C++, VB#, J# (Commercial)
- OOJNI Add-in (C#,VB#) for VS2005/2008 Generates object-oriented JNI code in C# or VB# for Java classes selected, implements Java interfaces and Java native methods in VB# and C#. Java Class methods and fields (which are represented as .NET Class properties) to be wrapped can be filtered. (Commercial)
- eXtremeDB JNI uses Java annotations and reflectionReflection (computer science)In computer science, reflection is the process by which a computer program can observe and modify its own structure and behavior at runtime....
to enable Java applications to call the eXtremeDB database (written in C) without reliance on an external database definition language