This Annex to the Java SE 9 Specification contains a draft of the Java SE 9 version of The Java Native Interface Specification (JNI).
The draft for Proposed Final Draft includes all changes made to the JNI Specification between Java SE 8 and Java SE 9, including trivial changes such as corrections of typographical errors and misspellings. Insertions are shown on a light green background and deletions are shown struck through on a light red background. This draft includes additions for JSR 376 Java Platform Module System which are unrelated to this specification but are difficult to exclude.
Additional information about changes to this specification may be found in 8155881 and 8079466.
Contents | |
---|---|
1 | Introduction |
2 | Design Overview |
3 | JNI Types and Data Structures |
4 | JNI Functions |
5 | The Invocation API |
This chapter introduces the Java Native Interface (JNI). The JNI is a native programming interface. It allows Java code that runs inside a Java Virtual Machine (VM) to interoperate with applications and libraries written in other programming languages, such as C, C++, and assembly.
The most important benefit of the JNI is that it imposes no restrictions on the implementation of the underlying Java VM. Therefore, Java VM vendors can add support for the JNI without affecting other parts of the VM. Programmers can write one version of a native application or library and expect it to work with all Java VMs supporting the JNI.
This chapter covers the following topics:
While you can write applications entirely in Java, there are situations where Java alone does not meet the needs of your application. Programmers use the JNI to write Java native methods to handle those situations when an application cannot be written entirely in Java.
The following examples illustrate when you need to use Java native methods:
By programming through the JNI, you can use native methods to:
You can also use the JNI with the Invocation API to enable an arbitrary native application to embed the Java VM. This allows programmers to easily make their existing applications Java-enabled without having to link with the VM source code.
VMs from different vendors offer different native method interfaces. These different interfaces force programmers to produce, maintain, and distribute multiple versions of native method libraries on a given platform.
We briefly examine some of the native method interfaces, such as:
JDK 1.0 was shipped with a native method interface. Unfortunately, there were two major reasons that this interface was unsuitable for adoption by other Java VMs.
First, the native code accessed fields in Java objects as members of C structures. However, the Java Language Specification does not define how objects are laid out in memory. If a Java VM lays out objects differently in memory, then the programmer would have to recompile the native method libraries.
Second, JDK 1.0's native method interface relied on a conservative garbage collector. The unrestricted use of the unhand
macro, for example, made it necessary to conservatively scan the native stack.
Netscape had proposed the Java Runtime Interface (JRI), a general interface for services provided in the Java virtual machine. JRI was designed with portability in mind---it makes few assumptions about the implementation details in the underlying Java VM. The JRI addressed a wide range of issues, including native methods, debugging, reflection, embedding (invocation), and so on.
The Microsoft Java VM supports two native method interfaces. At the low level, it provides an efficient Raw Native Interface (RNI). The RNI offers a high degree of source-level backward compatibility with the JDK‘s native method interface, although it has one major difference. Instead of relying on conservative garbage collection, the native code must use RNI functions to interact explicitly with the garbage collector.
At a higher level, Microsoft's Java/COM interface offers a language-independent standard binary interface to the Java VM. Java code can use a COM object as if it were a Java object. A Java class can also be exposed to the rest of the system as a COM class.
We believe that a uniform, well-thought-out standard interface offers the following benefits for everyone:
The best way to achieve a standard native method interface is to involve all parties with an interest in Java VMs. Therefore we organized a series of discussions among the Java licensees on the design of a uniform native method interface. It is clear from the discussions that the standard native method interface must satisfy the following requirements:
We hoped to adopt one of the existing approaches as the standard interface, because this would have imposed the least burden on programmers who had to learn multiple interfaces in different VMs. Unfortunately, no existing solutions are completely satisfactory in achieving our goals.
Netscape‘s JRI is the closest to what we envision as a portable native method interface, and was used as the starting point of our design. Readers familiar with the JRI will notice the similarities in the API naming convention, the use of method and field IDs, the use of local and global references, and so on. Despite our best efforts, however, the JNI is not binary-compatible with the JRI, although a VM can support both the JRI and the JNI.
Microsoft‘s RNI was an improvement over JDK 1.0 because it solved the problem of native methods working with a nonconservative garbage collector. The RNI, however, was not suitable as a VM-independent native method interface. Like the JDK, RNI native methods access Java objects as C structures, leading to two problems:
As a binary standard, COM ensures complete binary compatibility across different VMs. Invoking a COM method requires only an indirect call, which carries little overhead. In addition, COM objects are a great improvement over dynamic-link libraries in solving versioning problems.
The use of COM as the standard Java native method interface, however, is hampered by a few factors:
Although Java objects are not exposed to the native code as COM objects, the JNI interface itself is binary-compatible with COM. JNI uses the same jump table structure and calling convention that COM does. This means that, as soon as cross-platform support for COM is available, the JNI can become a COM interface to the Java VM.
JNI is not believed to be the only native method interface supported by a given Java VM. A standard interface benefits programmers, who would like to load their native code libraries into different Java VMs. In some cases, the programmer may have to use a lower-level, VM-specific interface to achieve top efficiency. In other cases, the programmer might use a higher-level interface to build software components. Indeed, as the Java environment and component software technologies become more mature, native methods will gradually lose their significance.
Native method programmers should program to the JNI. Programming to the JNI insulates you from unknowns, such as the vendor‘s VM that the end user might be running. By conforming to the JNI standard, you will give a native library the best chance to run in a given Java VM.
If you are implementing a Java VM, you should implement the JNI. JNI has been time tested and ensured to not impose any overhead or restrictions on your VM implementation, including object representation, garbage collection scheme, and so on. Please send us your feedback if you run into any problems we may have overlooked.
As of Java SE 6.0, the deprecated structures JDK1_1InitArgs and JDK1_1AttachArgs have been removed, instead JavaVMInitArgs and JavaVMAttachArgs are to be used .
This chapter focuses on major design issues in the JNI. Most design issues in this section are related to native methods. The design of the Invocation API is covered in Chapter 5: The Invocation API .
This chapter covers the following topics:
Native code accesses Java VM features by calling JNI functions. JNI functions are available through an interface pointer . An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function. Every interface function is at a predefined offset inside the array. The following figure, Interface Pointer , illustrates the organization of an interface pointer.
Description of Figure Interface Pointer
The JNI interface is organized like a C++ virtual function table or a COM interface. The advantage to using an interface table, rather than hard-wired function entries, is that the JNI name space becomes separate from the native code. A VM can easily provide multiple versions of JNI function tables. For example, the VM may support two JNI function tables:
The JNI interface pointer is only valid in the current thread. A native method, therefore, must not pass the interface pointer from one thread to another. A VM implementing the JNI may allocate and store thread-local data in the area pointed to by the JNI interface pointer.
Native methods receive the JNI interface pointer as an argument. The VM is guaranteed to pass the same interface pointer to a native method when it makes multiple calls to the native method from the same Java thread. However, a native method can be called from different Java threads, and therefore may receive different JNI interface pointers.
Since the Java VM is multithreaded, native libraries should also be compiled and linked with multithread aware native compilers. For example, the -mt
flag should be used for C++ code compiled with the Sun Studio compiler. For code complied with the GNU gcc compiler, the flags -D_REENTRANT
or -D_POSIX_C_SOURCE
should be used. For more information please refer to the native compiler documentation.
Native methods are loaded with the System.loadLibrary
method. In the following example, the class initialization method loads a platform-specific native library in which the native method f
is defined:
package pkg; class Cls { native double f(int i, String s); static { System.loadLibrary(“pkg_Cls”); } }
The argument to System.loadLibrary
is a library name chosen arbitrarily by the programmer. The system follows a standard, but platform-specific, approach to convert the library name to a native library name. For example, a Solaris system converts the name pkg_Cls
to libpkg_Cls.so
, while a Win32 system converts the same pkg_Cls
name to pkg_Cls.dll
.
The programmer may use a single library to store all the native methods needed by any number of classes, as long as these classes are to be loaded with the same class loader. The VM internally maintains a list of loaded native libraries for each class loader. Vendors should choose native library names that minimize the chance of name clashes.A native library may be statically linked with the VM. The manner in which the library
Support
for
both
dynamically
and
VM
image
are
combined
is
implementation
dependent.
A
System.loadLibrary
or
equivalent
API
must
succeed
for
this
library
to
be
considered
loaded.
A
library
L
whose
image
has
been
combined
with
the
VM
is
defined
as
statically linked
if
libraries,
and
only
if
the
library
exports
a
function
called
JNI_OnLoad_L
.If
a
statically
linked
library
L
exports
a
function
called
JNI_OnLoad_L
their
respective
lifecycle
management
"load" and
a
"unload"
function
called
JNI_OnLoad
,
hooks
are
detailed
in
the
JNI_OnLoad
function
will
be
ignored. If
a
library
L
is
statically
linked,
then
upon
the
first
invocation
of
System.loadLibrary("L")
or
equivalent
Invocation
API
,
a
JNI_OnLoad_L
function
will
be
invoked
with
the
same
arguments
section
on
Library
and
expected
return
value
as
specified
for
the
JNI_OnLoad
function
.
A
library
L
that
is
statically
linked
will
prohibit
a
library
of
the
same
name
from
being
loaded
dynamically.
When
the
class
loader
containing
a
statically
linked
native
library
L
is
garbage
collected,
the
VM
will
invoke
the
JNI_OnUnload_L
function
of
the
library
if
such
a
function
is
exported.
If
a
statically
linked
library
L
exports
a
function
called
JNI_OnUnLoad_L
and
a
function
called
JNI_OnUnLoad
,
the
JNI_OnUnLoad
function
will
be
ignored.
The
programmer
can
also
call
the
JNI
function
RegisterNatives()
to
register
the
native
methods
associated
with
a
class.
The
RegisterNatives()
function
is
particularly
useful
with
statically
linked
functions
Version
Management
.
Dynamic linkers resolve entries based on their names. A native method name is concatenated from the following components:
Java_
The VM checks for a method name match for methods that reside in the native library. The VM looks first for the short name; that is, the name without the argument signature. It then looks for the long name, which is the name with the argument signature. Programmers need to use the long name only when a native method is overloaded with another native method. However, this is not a problem if the native method has the same name as a nonnative method. A nonnative method (a Java method) does not reside in the native library.
In the following example, the native method g
does not have to be linked using the long name because the other method g
is not a native method, and thus is not in the native library.
class Cls1 { int g(int i); native int g(double d); }
We adopted a simple name-mangling scheme to ensure that all Unicode characters translate into valid C function names. We use the underscore (“_”) character as the substitute for the slash (“/”) in fully qualified class names. Since a name or type descriptor never begins with a number, we can use _0
, ..., _9
for escape sequences, as the following table illustrates:
Escape Sequence | Denotes |
---|---|
_0XXXX0xxxx |
a Unicode character
XXXXxxxx ,
representing
characters
other
than
ASCII
alphanumeric
([A-Za-z0-9]).
Note that lower case is used
to
represent
non-ASCII
Unicode
characters,
for example, _0abcd as opposed to _0ABCD .
|
_1 |
the character “_” |
_2 |
the character “;” in signatures |
_3 |
the character “[“ in signatures |
Both the native methods and the interface APIs follow the standard library-calling convention on a given platform. For example, UNIX systems use the C calling convention, while Win32 systems use __stdcall.
The JNI interface pointer is the first argument to native methods. The JNI interface pointer is of type JNIEnv. The second argument differs depending on whether the native method is static or nonstatic. The second argument to a nonstatic native method is a reference to the object. The second argument to a static native method is a reference to its Java class.
The remaining arguments correspond to regular Java method arguments. The native method call passes its result back to the calling routine via the return value. Chapter 3: JNI Types and Data Structures describes the mapping between Java and C types.
The following code example illustrates using a C function to implement the native method f
. The native method f
is declared as follows:
package pkg; class Cls { native double f(int i, String s); // ... }
The C function with the long mangled name Java_pkg_Cls_f_ILjava_lang_String_2
implements native method f
:
jdouble Java_pkg_Cls_f__ILjava_lang_String_2 ( JNIEnv *env, /* interface pointer */ jobject obj, /* "this" pointer */ jint i, /* argument #1 */ jstring s) /* argument #2 */ { /* Obtain a C-copy of the Java string */ const char *str = (*env)->GetStringUTFChars(env, s, 0); /* process the string */ ... /* Now we are done with str */ (*env)->ReleaseStringUTFChars(env, s, str); return ... }
Note that we always manipulate Java objects using the interface pointer env. Using C++, you can write a slightly cleaner version of the code, as shown in the following code example:
extern "C" /* specify the C calling convention */ jdouble Java_pkg_Cls_f__ILjava_lang_String_2 ( JNIEnv *env, /* interface pointer */ jobject obj, /* "this" pointer */ jint i, /* argument #1 */ jstring s) /* argument #2 */ { const char *str = env->GetStringUTFChars(s, 0); // ... env->ReleaseStringUTFChars(s, str); // return ... }
With C++, the extra level of indirection and the interface pointer argument disappear from the source code. However, the underlying mechanism is exactly the same as with C. In C++, JNI functions are defined as inline member functions that expand to their C counterparts.
Primitive types, such as integers, characters, and so on, are copied between Java and native code. Arbitrary Java objects, on the other hand, are passed by reference. The VM must keep track of all objects that have been passed to the native code, so that these objects are not freed by the garbage collector. The native code, in turn, must have a way to inform the VM that it no longer needs the objects. In addition, the garbage collector must be able to move an object referred to by the native code.
The JNI divides object references used by the native code into two categories: local and global references . Local references are valid for the duration of a native method call, and are automatically freed after the native method returns. Global references remain valid until they are explicitly freed.
Objects are passed to native methods as local references. All Java objects returned by JNI functions are local references. The JNI allows the programmer to create global references from local references. JNI functions that expect Java objects accept both global and local references. A native method may return a local or global reference to the VM as its result.
In most cases, the programmer should rely on the VM to free all local references after the native method returns. However, there are times when the programmer should explicitly free a local reference. Consider, for example, the following situations:
The JNI allows the programmer to manually delete local references at any point within a native method. To ensure that programmers can manually free local references, JNI functions are not allowed to create extra local references, except for references they return as the result.
Local references are only valid in the thread in which they are created. The native code must not pass local references from one thread to another.
To implement local references, the Java VM creates a registry for each transition of control from Java to a native method. A registry maps nonmovable local references to Java objects, and keeps the objects from being garbage collected. All Java objects passed to the native method (including those that are returned as the results of JNI function calls) are automatically added to the registry. The registry is deleted after the native method returns, allowing all of its entries to be garbage collected.
There are different ways to implement a registry, such as using a table, a linked list, or a hash table. Although reference counting may be used to avoid duplicated entries in the registry, a JNI implementation is not obliged to detect and collapse duplicate entries.
Note that local references cannot be faithfully implemented by conservatively scanning the native stack. The native code may store local references into global or heap data structures.
The JNI provides a rich set of accessor functions on global and local references. This means that the same native method implementation works no matter how the VM represents Java objects internally. This is a crucial reason why the JNI can be supported by a wide variety of VM implementations.
The overhead of using accessor functions through opaque references is higher than that of direct access to C data structures. We believe that, in most cases, Java programmers use native methods to perform nontrivial tasks that overshadow the overhead of this interface.
This overhead is not acceptable for large Java objects containing many primitive data types, such as integer arrays and strings. (Consider native methods that are used to perform vector and matrix calculations.) It would be grossly inefficient to iterate through a Java array and retrieve every element with a function call.
One solution introduces a notion of “pinning” so that the native method can ask the VM to pin down the contents of an array. The native method then receives a direct pointer to the elements. This approach, however, has two implications:
We adopt a compromise that overcomes both of the above problems.
First, we provide a set of functions to copy primitive array elements between a segment of a Java array and a native memory buffer. Use these functions if a native method needs access to only a small number of elements in a large array.
Second, programmers can use another set of functions to retrieve a pinned-down version of array elements. Keep in mind that these functions may require the Java VM to perform storage allocation and copying. Whether these functions in fact copy the array depends on the VM implementation, as follows:
Lastly, the interface provides functions to inform the VM that the native code no longer needs to access the array elements. When you call these functions, the system either unpins the array, or it reconciles the original array with its non-movable copy and frees the copy.
Our approach provides flexibility. A garbage collector algorithm can make separate decisions about copying or pinning for each given array. For example, the garbage collector may copy small objects, but pin the larger objects.
A JNI implementation must ensure that native methods running in multiple threads can simultaneously access the same array. For example, the JNI may keep an internal counter for each pinned array so that one thread does not unpin an array that is also pinned by another thread. Note that the JNI does not need to lock primitive arrays for exclusive access by a native method. Simultaneously updating a Java array from different threads leads to nondeterministic results.
The JNI allows native code to access the fields and to call the methods of Java objects. The JNI identifies methods and fields by their symbolic names and type signatures. A two-step process factors out the cost of locating the field or method from its name and signature. For example, to call the method f
in class cls, the native code first obtains a method ID, as follows:
jmethodID mid = env->GetMethodID(cls, “f”, “(ILjava/lang/String;)D”);
The native code can then use the method ID repeatedly without the cost of method lookup, as follows:
jdouble result = env->CallDoubleMethod(obj, mid, 10, str);
A field or method ID does not prevent the VM from unloading the class from which the ID has been derived. After the class is unloaded, the method or field ID becomes invalid. The native code, therefore, must make sure to:
if it intends to use a method or field ID for an extended period of time.
The JNI does not impose any restrictions on how field and method IDs are implemented internally.
The JNI does not check for programming errors such as passing in NULL pointers or illegal argument types. Illegal argument types includes such things as using a normal Java object instead of a Java class object. The JNI does not check for these programming errors for the following reasons:
Most C library functions do not guard against programming errors. The printf()
function, for example, usually causes a runtime error, rather than returning an error code, when it receives an invalid address. Forcing C library functions to check for all possible error conditions would likely result in such checks to be duplicated--once in the user code, and then again in the library.
The programmer must not pass illegal pointers or arguments of the wrong type to JNI functions. Doing so could result in arbitrary consequences, including a corrupted system state or VM crash.
The JNI allows native methods to raise arbitrary Java exceptions. The native code may also handle outstanding Java exceptions. The Java exceptions left unhandled are propagated back to the VM.
Certain JNI functions use the Java exception mechanism to report error conditions. In most cases, JNI functions report error conditions by returning an error code and throwing a Java exception. The error code is usually a special return value (such as NULL) that is outside of the range of normal return values. Therefore, the programmer can:
ExceptionOccurred()
, to obtain the exception object that contains a more detailed description of the error condition. There are two cases where the programmer needs to check for exceptions without being able to first check an error code:
ExceptionOccurred()
to check for possible exceptions that occurred during the execution of the Java method. ArrayIndexOutOfBoundsException
or ArrayStoreException
. In all other cases, a non-error return value guarantees that no exceptions have been thrown.
In cases of multiple threads, threads other than the currentOne thread may postraise an asynchronous exception . Anin another thread by calling the Thread.stop()
method, which has been deprecated since Java 2 SDK release 1.2. Programmers are strongly discouraged from using Thread.stop()
as it generally leads to an indeterminate application state.
Furthermore, the JVM may produce exceptions in the current thread without being the direct result of a JNI API call, but because of various JVM internal errors, for example: VirtualMachineError
like StackOverflowError
or OutOfMemoryError
. These are also referred to as asynchronous exception doesexceptions.
Asynchronous exceptions do not immediately affect the execution of the native code in the current thread, until:
ExceptionOccurred()
to explicitly check for synchronous and asynchronous exceptions. Note that only those JNI functionfunctions that could potentially raise synchronous exceptions check for asynchronous exceptions.
Native methods should insert ExceptionOccurred()
checks in necessary places (, such as in a tight loopany long running code without other exception checks ) to ensure(this may include tight loops). This ensures that the current thread responds to asynchronous exceptions in a reasonable amount of time. However, because of their asynchronous nature, making an exception check before a call is no guarantee that an asynchronous exception won't be raised between the check and the call.
There are two ways to handle an exception in native code:
ExceptionClear()
, and then execute its own exception-handling code. After an exception has been raised, the native code must first clear the exception before making other JNI calls. When there is a pending exception, the JNI functions that are safe to call are:
ExceptionOccurred() ExceptionDescribe() ExceptionClear() ExceptionCheck() ReleaseStringChars() ReleaseStringUTFChars() ReleaseStringCritical() Release<Type>ArrayElements() ReleasePrimitiveArrayCritical() DeleteLocalRef() DeleteGlobalRef() DeleteWeakGlobalRef() MonitorExit() PushLocalFrame() PopLocalFrame() DetachCurrentThread()
This chapter discusses how the JNI maps Java types to native C types.
This chapter covers the following topics:
The following table describes Java primitive types and their machine-dependent native equivalents.
Java Type | Native Type | Description |
---|---|---|
boolean | jboolean | unsigned 8 bits |
byte | jbyte | signed 8 bits |
char | jchar | unsigned 16 bits |
short | jshort | signed 16 bits |
int | jint | signed 32 bits |
long | jlong | signed 64 bits |
float | jfloat | 32 bits |
double | jdouble | 64 bits |
void | void | not applicable |
The following definition is provided for convenience.
#define JNI_FALSE 0 #define JNI_TRUE 1
The jsize
integer type is used to describe cardinal indices
and sizes:
typedef jint jsize;
The JNI includes a number of reference types that correspond to different kinds of Java objects. JNI reference types are organized in the following hierarchy:
jclass
(java.lang.Class
objects) jstring
(java.lang.String
objects) jarray
(arrays)jobjectArray
(object arrays) jbooleanArray
(boolean
arrays) jbyteArray
(byte
arrays) jcharArray
(char
arrays) jshortArray
(short
arrays) jintArray
(int
arrays) jlongArray
(long
arrays) jfloatArray
(float
arrays) jdoubleArray
(double
arrays) jthrowable
(java.lang.Throwable
objects) In C, all other JNI reference types are defined to be the same as jobject. For example:
typedef jobject jclass;
In C++, JNI introduces a set of dummy classes to enforce the subtyping relationship. For example:
class _jobject {}; class _jclass : public _jobject {}; // ... typedef _jobject *jobject; typedef _jclass *jclass;
Method and field IDs are regular C pointer types:
struct _jfieldID; /* opaque structure */ typedef struct _jfieldID *jfieldID; /* field IDs */ struct _jmethodID; /* opaque structure */ typedef struct _jmethodID *jmethodID; /* method IDs */
The jvalue
union type is used as the element type in argument arrays. It is declared as follows:
typedef union jvalue { jboolean z; jbyte b; jchar c; jshort s; jint i; jlong j; jfloat f; jdouble d; jobject l; } jvalue;
The JNI uses the Java VM‘s representation of type signatures. The following table shows these type signatures.
Type Signature | Java Type |
---|---|
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
L fully-qualified-class ; | fully-qualified-class |
[ type | type[] |
( arg-types ) ret-type | method type |
For example, the Java method:
long f (int n, String s, int[] arr);
has the following type signature:
(ILjava/lang/String;[I)J
The JNI uses modified UTF-8 strings to represent various string types. Modified UTF-8 strings are the same as those used by the Java VM. Modified UTF-8 strings are encoded so that character sequences that contain only non-null ASCII characters can be represented using only one byte per character, but all Unicode characters can be represented.
All characters in the range \u0001 to \u007F are represented by a single byte, as follows:
0xxxxxxx
The seven bits of data in the byte give the value of the character represented.
The null character ('\u0000'
) and characters in the range '\u0080'
to '\u07FF'
are represented by a pair of bytes x and y:
110xxxxx
10yyyyyy
The bytes represent the character with the value ((x & 0x1f
) << 6
) + (y & 0x3f
).
Characters in the range '\u0800'
to '\uFFFF'
are represented by 3 bytes x, y, and z:
1110xxxx
10yyyyyy
10zzzzzz
The character with the value ((x & 0xf
) << 12
) + ((y & 0x3f
) << 6
) + (z & 0x3f
) is represented by the bytes.
Characters with code points above U+FFFF (so-called supplementary characters ) are represented by separately encoding the two surrogate code units of their UTF-16 representation. Each of the surrogate code units is represented by three bytes. This means, supplementary characters are represented by six bytes, u, v, w, x, y, and z:
11101101
1010vvvv
10wwwwww
11101101
1011yyyy
10zzzzzz
The character with the value 0x10000+((v&0x0f)<<16)+((w&0x3f)<<10)+(y&0x0f)<<6)+(z&0x3f) is represented by the six bytes.
The bytes of multibyte characters are stored in the class
file in big-endian (high byte first) order.
There are two differences between this format and the standard UTF-8 format. First, the null character (char)0
is encoded using the two-byte format rather than the one-byte format. This means that modified UTF-8 strings never have embedded nulls. Second, only the one-byte, two-byte, and three-byte formats of standard UTF-8 are used. The Java VM does not recognize the four-byte format of standard UTF-8; it uses its own two-times-three-byte format instead.
For more information regarding the standard UTF-8 format, see section 3.9 Unicode Encoding Forms of The Unicode Standard, Version 4.0 .
This chapter serves as the reference section for the JNI functions. It provides a complete listing of all the JNI functions. It also presents the exact layout of the JNI function table.
Note the use of the term “must” to describe restrictions on JNI programmers. For example, when you see that a certain JNI function must receive a non-NULL object, it is your responsibility to ensure that NULL is not passed to that JNI function. As a result, a JNI implementation does not need to perform NULL pointer checks in that JNI function. Passing NULL when explicity not allowed may result in an unexpected exception or a fatal crash.
Functions whose definition may both return NULL
and throw an exception on error, may choose only to return NULL
to indicate an error, but not throw any exception. For example, a JNI implementation may consider an "out of memory" condition temporary, and may not wish to throw an OutOfMemoryError
since this would appear fatal (JDK API java.lang.Error
documentation: "indicates serious problems that a reasonable application should not try to catch" ).
A portion of this chapter is adapted from Netscape‘s JRI documentation.
The reference material groups functions by their usage. The reference section is organized by the following functional areas:
Each function is accessible at a fixed offset through the JNIEnv argument. The JNIEnv type is a pointer to a structure storing all JNI function pointers. It is defined as follows:
typedef const struct JNINativeInterface *JNIEnv;
The VM initializes the function table, as shown by the following code example. Note that the first three entries are reserved for future compatibility with COM. In addition, we reserve a number of additional NULL
entries near the beginning of the function table, so that, for example, a future class-related JNI operation can be added after FindClass, rather than at the end of the table.
Note that the function table can be shared among all JNI interface pointers.
const struct JNINativeInterface ... = { NULL, NULL, NULL, NULL, GetVersion, DefineClass, FindClass, FromReflectedMethod, FromReflectedField, ToReflectedMethod, GetSuperclass, IsAssignableFrom, ToReflectedField, Throw, ThrowNew, ExceptionOccurred, ExceptionDescribe, ExceptionClear, FatalError, PushLocalFrame, PopLocalFrame, NewGlobalRef, DeleteGlobalRef, DeleteLocalRef, IsSameObject, NewLocalRef, EnsureLocalCapacity, AllocObject, NewObject, NewObjectV, NewObjectA, GetObjectClass, IsInstanceOf, GetMethodID, CallObjectMethod, CallObjectMethodV, CallObjectMethodA, CallBooleanMethod, CallBooleanMethodV, CallBooleanMethodA, CallByteMethod, CallByteMethodV, CallByteMethodA, CallCharMethod, CallCharMethodV, CallCharMethodA, CallShortMethod, CallShortMethodV, CallShortMethodA, CallIntMethod, CallIntMethodV, CallIntMethodA, CallLongMethod, CallLongMethodV, CallLongMethodA, CallFloatMethod, CallFloatMethodV, CallFloatMethodA, CallDoubleMethod, CallDoubleMethodV, CallDoubleMethodA, CallVoidMethod, CallVoidMethodV, CallVoidMethodA, CallNonvirtualObjectMethod, CallNonvirtualObjectMethodV, CallNonvirtualObjectMethodA, CallNonvirtualBooleanMethod, CallNonvirtualBooleanMethodV, CallNonvirtualBooleanMethodA, CallNonvirtualByteMethod, CallNonvirtualByteMethodV, CallNonvirtualByteMethodA, CallNonvirtualCharMethod, CallNonvirtualCharMethodV, CallNonvirtualCharMethodA, CallNonvirtualShortMethod, CallNonvirtualShortMethodV, CallNonvirtualShortMethodA, CallNonvirtualIntMethod, CallNonvirtualIntMethodV, CallNonvirtualIntMethodA, CallNonvirtualLongMethod, CallNonvirtualLongMethodV, CallNonvirtualLongMethodA, CallNonvirtualFloatMethod, CallNonvirtualFloatMethodV, CallNonvirtualFloatMethodA, CallNonvirtualDoubleMethod, CallNonvirtualDoubleMethodV, CallNonvirtualDoubleMethodA, CallNonvirtualVoidMethod, CallNonvirtualVoidMethodV, CallNonvirtualVoidMethodA, GetFieldID, GetObjectField, GetBooleanField, GetByteField, GetCharField, GetShortField, GetIntField, GetLongField, GetFloatField, GetDoubleField, SetObjectField, SetBooleanField, SetByteField, SetCharField, SetShortField, SetIntField, SetLongField, SetFloatField, SetDoubleField, GetStaticMethodID, CallStaticObjectMethod, CallStaticObjectMethodV, CallStaticObjectMethodA, CallStaticBooleanMethod, CallStaticBooleanMethodV, CallStaticBooleanMethodA, CallStaticByteMethod, CallStaticByteMethodV, CallStaticByteMethodA, CallStaticCharMethod, CallStaticCharMethodV, CallStaticCharMethodA, CallStaticShortMethod, CallStaticShortMethodV, CallStaticShortMethodA, CallStaticIntMethod, CallStaticIntMethodV, CallStaticIntMethodA, CallStaticLongMethod, CallStaticLongMethodV, CallStaticLongMethodA, CallStaticFloatMethod, CallStaticFloatMethodV, CallStaticFloatMethodA, CallStaticDoubleMethod, CallStaticDoubleMethodV, CallStaticDoubleMethodA, CallStaticVoidMethod, CallStaticVoidMethodV, CallStaticVoidMethodA, GetStaticFieldID, GetStaticObjectField, GetStaticBooleanField, GetStaticByteField, GetStaticCharField, GetStaticShortField, GetStaticIntField, GetStaticLongField, GetStaticFloatField, GetStaticDoubleField, SetStaticObjectField, SetStaticBooleanField, SetStaticByteField, SetStaticCharField, SetStaticShortField, SetStaticIntField, SetStaticLongField, SetStaticFloatField, SetStaticDoubleField, NewString, GetStringLength, GetStringChars, ReleaseStringChars, NewStringUTF, GetStringUTFLength, GetStringUTFChars, ReleaseStringUTFChars, GetArrayLength, NewObjectArray, GetObjectArrayElement, SetObjectArrayElement, NewBooleanArray, NewByteArray, NewCharArray, NewShortArray, NewIntArray, NewLongArray, NewFloatArray, NewDoubleArray, GetBooleanArrayElements, GetByteArrayElements, GetCharArrayElements, GetShortArrayElements, GetIntArrayElements, GetLongArrayElements, GetFloatArrayElements, GetDoubleArrayElements, ReleaseBooleanArrayElements, ReleaseByteArrayElements, ReleaseCharArrayElements, ReleaseShortArrayElements, ReleaseIntArrayElements, ReleaseLongArrayElements, ReleaseFloatArrayElements, ReleaseDoubleArrayElements, GetBooleanArrayRegion, GetByteArrayRegion, GetCharArrayRegion, GetShortArrayRegion, GetIntArrayRegion, GetLongArrayRegion, GetFloatArrayRegion, GetDoubleArrayRegion, SetBooleanArrayRegion, SetByteArrayRegion, SetCharArrayRegion, SetShortArrayRegion, SetIntArrayRegion, SetLongArrayRegion, SetFloatArrayRegion, SetDoubleArrayRegion, RegisterNatives, UnregisterNatives, MonitorEnter, MonitorExit, GetJavaVM, GetStringRegion, GetStringUTFRegion, GetPrimitiveArrayCritical, ReleasePrimitiveArrayCritical, GetStringCritical, ReleaseStringCritical, NewWeakGlobalRef, DeleteWeakGlobalRef, ExceptionCheck, NewDirectByteBuffer, GetDirectBufferAddress, GetDirectBufferCapacity, GetObjectRefType, GetModule };
#define JNI_FALSE 0 #define JNI_TRUE 1
General return value constants for JNI functions.
#define JNI_OK 0 /* success */ #define JNI_ERR (-1) /* unknown error */ #define JNI_EDETACHED (-2) /* thread detached from the VM */ #define JNI_EVERSION (-3) /* JNI version error */ #define JNI_ENOMEM (-4) /* not enough memory */ #define JNI_EEXIST (-5) /* VM already created */ #define JNI_EINVAL (-6) /* invalid arguments */
jint GetVersion(JNIEnv *env);
Returns the version of the native method interface. The following table gives the version of JNI included in each release of the Java SE Platform (for older versions of JNI, the JDK release is used instead of the Java SE Platform):
Java SE Platform JNI Version 1.1 JNI_VERSION_1_1
1.2 JNI_VERSION_1_2
1.3 JNI_VERSION_1_2
1.4 JNI_VERSION_1_4
5.0 JNI_VERSION_1_4
6 JNI_VERSION_1_6
7 JNI_VERSION_1_6
8 JNI_VERSION_1_8
9 JNI_VERSION_9
Index 4 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
Returns the major version number in the higher 16 bits and the minor version number in the lower 16 bits.
In JDK/JRE 1.1, GetVersion()
returns 0x00010001JNI_VERSION_1_1
.
In JDK/JRE 1.2, GetVersion()
returns 0x00010002JNI_VERSION_1_2
.
In JDK/JRE 1.4, GetVersion()
returns 0x00010004JNI_VERSION_1_4
.
In JDK/JRE 1.6, GetVersion()
returns 0x00010006
.
SINCEJNI_VERSION_1_6
.
In JDK/JRE 1.2:8, GetVersion()
returns JNI_VERSION_1_8
.
In JDK/JRE 9, GetVersion()
returns JNI_VERSION_9
.
#define JNI_VERSION_1_1 0x00010001 #define JNI_VERSION_1_2 0x00010002 /*Errorcodes*/#define JNI_VERSION_1_EDETACHED4 (-2)/*threaddetachedfromtheVM*/0x00010004 #define JNI_VERSION_1_EVERSION6 (-3)/*JNIversionerror0x00010006 SINCEJDK/JRE1.4: #define JNI_VERSION_1_48 0x000100040x00010008 SINCEJDK/JRE1.6: #define JNI_VERSION_1_69 0x000100060x00090000
jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
const jbyte *buf, jsize bufLen);
Loads a class from a buffer of raw class data. The buffer containing the raw class data is not referenced by the VM after the DefineClass call returns, and it may be discarded if desired.
Index 5 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
name
: the name of the class or interface to be defined. The string is encoded in modified UTF-8. This value may be NULL
, or it must match the name encoded within the class file data.
loader
: a class loader assigned to the defined class. This value may be NULL
, indicating the "null class loader" (or "bootstrap class loader" ).
buf
: buffer containing the .class
file data. A NULL
value will cause a ClassFormatError
.
bufLen
: buffer length.
Returns a Java class object or NULL
if an error occurs.
ClassFormatError
: if the class data does not specify a valid class.
ClassCircularityError
: if a class or interface would be its own superclass or superinterface.
OutOfMemoryError
: if the system runs out of memory.
SecurityException
: if the caller attempts to define a class in the "java" package tree.
jclass FindClass(JNIEnv *env, const char *name);
In JDK release 1.1, this function loads a locally-defined class. It searches the directories and zip files specified by the CLASSPATH
environment variable for the class with the specified name.
Since Java 2 SDK releaseJDK 1.2, the Java security model allows non-system classes to load and call native methods. FindClass
locates the class loader associated with the current native method; that is, the class loader of the class that declared the native method. If the native method belongs to a system class, no class loader will be involved. Otherwise, the proper class loader will be invoked to load and link the named class.
Since Java 2 SDK releaseJDK 1.2, when FindClass
is called through the Invocation Interface, there is no current native method or its associated class loader. In that case, the result of ClassLoader.getSystemClassLoader
is used. This is the class loader the virtual machine creates for applications, and is able to locate classes listed in the java.class.path
property.
The name
argument is a fully-qualified class name or an array type signature . For example, the fully-qualified class name for the java.lang.String
class is:
“java/lang/String”
The array type signature of the array class java.lang.Object[]
is:
“[Ljava/lang/Object;”
Index 6 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
name
: a fully-qualified class name (that is, a package name, delimited by “/
”, followed by the class name). If the name begins with “[
“ (the array signature character), it returns an array class. The string is encoded in modified UTF-8. A NULL
value may cause NoClassDefFoundError
to occur, or a crash.
Returns a class object from a fully-qualified name, or NULL
if the class cannot be found.
ClassFormatError
: if the class data does not specify a valid class.
ClassCircularityError
: if a class or interface would be its own superclass or superinterface.
NoClassDefFoundError
: if no definition for a requested class or interface can be found.
OutOfMemoryError
: if the system runs out of memory.
jclass GetSuperclass(JNIEnv *env, jclass clazz);
If clazz
represents any class other than the class Object
, then this function returns the object that represents the superclass of the class specified by clazz
.
If clazz
specifies the class Object
, or clazz
represents an interface, this function returns NULL
.
Index 10 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
Returns the superclass of the class represented by clazz
, or NULL
.
jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1,
jclass clazz2);
Determines whether an object of clazz1
can be safely cast to clazz2
.
Index 11 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz1
: the first class argument, must not be NULL
.
clazz2
: the second class argument, must not be NULL
.
Returns JNI_TRUE
if either of the following is true:
jobject GetModule(JNIEnv *env, jclass clazz);
Returns the java.lang.reflect.Module
object for the module that the class is a member of. If the class is not in a named module then the unnamed module of the class loader for the class is returned. If the class represents an array type then this function returns the Module
object for the element type. If the class represents a primitive type or void
, then the Module
object for the java.base
module is returned.
Index 233 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
Returns the module that the class or interface is a member of.
JDK/JRE 9
jint Throw(JNIEnv *env, jthrowable obj);
Causes a java.lang.Throwable
object to be thrown.
Index 13 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
obj
: a java.lang.Throwable
object, must not be NULL
.
Returns 0 on success; a negative value on failure.
the java.lang.Throwable
object
obj
.
jint ThrowNew(JNIEnv *env, jclass clazz,
const char *message);
Constructs an exception object from the specified class with the message specified by message
and causes that exception to be thrown.
Index 14 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a subclass of java.lang.Throwable
, must not be NULL
.
message
: the message used to construct the java.lang.Throwable
object. The string is encoded in modified UTF-8. This value may be NULL
.
Returns 0 on success; a negative value on failure.
the newly constructed java.lang.Throwable
object.
jthrowable ExceptionOccurred(JNIEnv *env);
Determines if an exception is being thrown. The exception stays being thrown until either the native code calls ExceptionClear()
, or the Java code handles the exception.
Index 15 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
Returns the exception object that is currently in the process of being thrown, or NULL
if no exception is currently being thrown.
void ExceptionDescribe(JNIEnv *env);
Prints an exception and a backtrace of the stack to a system error-reporting channel, such as stderr
. The pending exception is cleared as a side-effect of calling this function. This is a convenience routine provided for debugging.
Index 16 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
void ExceptionClear(JNIEnv *env);
Clears any exception that is currently being thrown. If no exception is currently being thrown, this routine has no effect.
Index 17 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
void FatalError(JNIEnv *env, const char *msg);
Raises a fatal error and does not expect the VM to recover. This function does not return.
Index 18 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
msg
: an error message. The string is encoded in modified UTF-8. May be a NULL
value.
jboolean ExceptionCheck(JNIEnv *env);
Returns JNI_TRUE
when there is a pending exception; otherwise, returns JNI_FALSE
.
Index 228 in the JNIEnv interface function table.
JDK/JRE 1.2
env
: the JNI interface pointer, must not be NULL
.
jobject NewGlobalRef(JNIEnv *env, jobject obj);
Creates a new global reference to the object referred to by the obj
argument. The obj
argument may be a global or local reference. Global references must be explicitly disposed of by calling DeleteGlobalRef()
.
Index 21 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
obj
: a global or local reference. May be a NULL
value, in which case this function will return NULL
.
Returns a global reference, or NULL
if the given obj
value was NULL
, or system runs out of memory.
void DeleteGlobalRef(JNIEnv *env, jobject globalRef);
Deletes the global reference pointed to by globalRef
.
Index 22 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
globalRef
: a global reference. May be a NULL
value, in which case this function does nothing.
Local references are valid for the duration of a native method call. They are freed automatically after the native method returns. Each local reference costs some amount of Java Virtual Machine resource. Programmers need to make sure that native methods do not excessively allocate local references. Although local references are automatically freed after the native method returns to Java, excessive allocation of local references may cause the VM to run out of memory during the execution of a native method.
void DeleteLocalRef(JNIEnv *env, jobject localRef);
Deletes the local reference pointed to by localRef
.
Index 23 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
localRef
: a local reference. The function does nothing in the case of a NULL
value passed here.
Note: JDK/JRE 1.1 provides the DeleteLocalRef
function above so that programmers can manually delete local references. For example, if native code iterates through a potentially large array of objects and uses one element in each iteration, it is a good practice to delete the local reference to the no-longer-used array element before a new local reference is created in the next iteration. As of JDK/JRE 1.2 an additional set of functions are provided for local reference lifetime management. They are the four functions listed below.
jint EnsureLocalCapacity(JNIEnv *env, jint capacity);
Ensures that at least a given number of local references can be created in the current thread. Returns 0 on success; otherwise returns a negative number and throws an OutOfMemoryError
.
Before it enters a native method, the VM automatically ensures that at least 16 local references can be created.
For backward compatibility, the VM allocates local references beyond the ensured capacity. (As a debugging support, the VM may give the user warnings that too many local references are being created. In the JDK, the programmer can supply the -verbose:jni
command line option to turn on these messages.) The VM calls FatalError
if no more local references can be created beyond the ensured capacity.
Some Java Virtual Machine implementations may choose to limit the maximum capacity
, which may cause the function to return an error (e.g. JNI_ERR
or JNI_EINVAL
). The HotSpot JVM implementation, for example, uses the -XX:+MaxJNILocalCapacity
flag (default: 65536).
env
: the JNI interface pointer, must not be NULL
.
capacity
: the minimum number of required local references. Must be >= 0.
JNI_OK
upon succcess.
JDK/JRE 1.2
jint PushLocalFrame(JNIEnv *env, jint capacity);
Creates a new local reference frame, in which at least a given number of local references can be created. Returns 0 on success, a negative number and a pending OutOfMemoryError
on failure.
Note that local references already created in previous local frames are still valid in the current local frame.
As with EnsureLocalCapacity
, some Java Virtual Machine implementations may choose to limit the maximum capacity
, which may cause the function to return an error.
env
: the JNI interface pointer, must not be NULL
.
capacity
: the minimum number of required local references. Must be > 0.
JNI_OK
upon succcess.
JDK/JRE 1.2
jobject PopLocalFrame(JNIEnv *env, jobject result);
Pops off the current local reference frame, frees all the local references, and returns a local reference in the previous local reference frame for the given result
object.
Pass NULL
as result
if you do not need to return a reference to the previous frame.
env
: the JNI interface pointer, must not be NULL
.
result
: an object to be passed to the previous local reference frame, may be NULL
.
Returns a local reference in the previous local reference frame for the given result
object, or NULL
if the given result
object was NULL
.
JDK/JRE 1.2
jobject NewLocalRef(JNIEnv *env, jobject ref);
Creates a new local reference that refers to the same object as ref
. The given ref
may be a global or, a local reference or NULL
. Returns NULL
if ref
refers to null
.
env
: the JNI interface pointer, must not be NULL
.
ref
: a reference to the object for which the function creates a new local reference. May be a NULL
value.
Returns a new local reference that refers to the same object as ref
.
May
return
NULL
if:
ref
refers
to
null
ref
was
a
weak
global
reference
and
has
already
been
garbage
collected
JDK/JRE 1.2
NULL
. Programmers can detect whether a weak global reference points to a freed object by using IsSameObject
to compare the weak reference against NULL
.Weak global references in JNI are a simplified version of the Java Weak References, available as part of the Java 2SE Platform API ( java.lang.ref
package and its classes).
Clarification (added June 2001)
Since garbage collection may occur while native methods are running, objects referred to by weak global references can be freed at any time. While weak global references can be used where global references are used, it is generally inappropriate to do so, as they may become functionally equivalent to NULL
without notice.
WhileIsSameObject
can be used to determine whether a weak global reference refers to a freed object, it does not prevent the object from being freed immediately thereafter. Consequently, programmers may not rely on this check to determine whether a weak global reference may used (as a non- NULL
reference) in any future JNI function call.
To overcome this inherent limitation, it is recommended that a standard (strong) local or global reference to the same object be acquired using the JNI functions NewLocalRef
orNewGlobalRef
, and that this strong reference be used to access the intended object. These functions will return NULL
if the object has been freed, and otherwise will return a strong reference (which will prevent the object from being freed). The new reference should be explicitly deleted when immediate access to the object is no longer required, allowing the object to be freed.
The weak global reference is weaker than other types of weak references (Java objects of the SoftReference or WeakReference classes). A weak global reference to a specific object will not become functionally equivalent to NULL
until after SoftReference or WeakReference objects referring to that same specific object have had their references cleared.
The weak global reference is weaker than Java's internal references to objects requiring finalization. A weak global reference will not become functionally equivalent to NULL
until after the completion of the finalizer for the referenced object, if present.
Interactions between weak global references and PhantomReferences are undefined. In particular, implementations of a Java VM may (or may not) process weak global references after PhantomReferences, and it may (or may not) be possible to use weak global references to hold on to objects which are also referred to by PhantomReference objects. This undefined use of weak global references should be avoided.
jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);
Creates a new weak global reference. The weak global reference will not prevent garbage collection of the given object. IsSameObject
may be used to test if the object referred to by the reference has been freed. Returns NULL
if obj
refers to null
, or if obj
was a weak global reference, or if the VM runs out of memory. If the VM runs out of memory, an OutOfMemoryError
will be thrown.
env
: the JNI interface pointer, must not be NULL
.
obj
: the object to create a global weak reference for.
Return a global weak reference to the given obj
.
May
return
NULL
if:
obj
refers
to
null
obj
was
a
weak
global
reference
and
has
already
been
garbage
collected
OutOfMemoryError
if
the
system
runs
out
of
memory.
JDK/JRE 1.2
void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);
Delete the VM resources needed for the given weak global reference.
env
: the JNI interface pointer, must not be NULL
.
obj
: global weak reference to delete. This function does nothing if passed NULL
.
jobject AllocObject(JNIEnv *env, jclass clazz);
Allocates a new Java object without invoking any of the constructors for the object . Returns a reference to the object.
Note: The Java Language Specification, "Implementing Finalization" (JLS 12.6.1 ) states: "An object o is not finalizable until its constructor has invoked the constructor for Object on o and that invocation has completed successfully". Since AllocObject() does not invoke a constructor, objects created with this function are not eligible for finalization.
The clazz argument must not refer to an array class.
Index 27 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a reference to a Java class object, must not be NULL
.
Returns a Java object, or NULL
if the object cannot be constructed.
InstantiationException
: if the class is an interface or an abstract class.
OutOfMemoryError
: if the system runs out of memory.
jobject NewObject(JNIEnv *env, jclass clazz,
jmethodID methodID, ...);
jobject NewObjectA(JNIEnv *env, jclass clazz,
jmethodID methodID, const jvalue *args);
jobject NewObjectV(JNIEnv *env, jclass clazz,
jmethodID methodID, va_list args);
Constructs a new Java object. The method ID indicates which constructor method to invoke. This ID must be obtained by calling GetMethodID()
with <init>
as the method name and void
(V
) as the return type.
The clazz
argument must not refer to an array class.
Programmers place all arguments that are to be passed to the constructor immediately following the methodID
argument. NewObject()
accepts these arguments and passes them to the Java method that the programmer wishes to invoke.
Index 28 in the JNIEnv interface function table.
Programmers place all arguments that are to be passed to the constructor in an args
array of jvalues
that immediately follows the methodID
argument. NewObjectA()
accepts the arguments in this array, and, in turn, passes them to the Java method that the programmer wishes to invoke.
Index 30 in the JNIEnv interface function table.
Programmers place all arguments that are to be passed to the constructor in an args
argument of type va_list
that immediately follows the methodID
argument. NewObjectV()
accepts these arguments, and, in turn, passes them to the Java method that the programmer wishes to invoke.
Index 29 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a reference to a Java class object, must not be NULL
.
methodID
: the method ID of the constructor.
arguments to the constructor.
args
: an array of arguments to the constructor.
args
: a va_list of arguments to the constructor.
Returns a Java object, or NULL
if the object cannot be constructed.
InstantiationException
: if the class is an interface or an abstract class.
OutOfMemoryError
: if the system runs out of memory.
Any exceptions thrown by the constructor.
jclass GetObjectClass(JNIEnv *env, jobject obj);
Returns the class of an object.
Index 31 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
obj
: a Java object (, must not be NULL
).
Returns a Java class object.
jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);
Returns the type of the object referred to by the obj
argument. The argument obj
can either be a local, global or weak global reference, or NULL
.
Index 232 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
obj
: a local, global or weak global reference. vm
: the virtual machine instance from which the interface will be retrieved. env
: pointer to the ___location where the JNI interface pointer for the current thread will be placed. version
: the requested JNI version.
The function GetObjectRefType
returns one of the following enumerated values defined as a jobjectRefType
:
JNIInvalidRefType = 0 ,JNILocalRefType = 1 ,JNIGlobalRefType = 2 ,JNIWeakGlobalRefType = 3
If the argument obj
is a weak global reference type, the return will be JNIWeakGlobalRefType
.
If the argument obj
is a global reference type, the return value will be JNIGlobalRefType
.
If the argument obj
is a local reference type, the return will be JNILocalRefType
.
If the obj
argument is not a valid reference, the return value for this function will be JNIInvalidRefType
.
An invalid reference is a reference which is not a valid handle. That is, the obj
pointer address does not point to a ___location in memory which has been allocated from one of the Ref creation functions or returned from a JNI function.
As such, NULL
would be an invalid reference and GetObjectRefType(env,NULL)
would return JNIInvalidRefType
.
On the other hand, a null reference, which is a reference that points to a null, would return the type of reference that the null reference was originally created as.
GetObjectRefType
cannot be used on deleted references.
Since references are typically implemented as pointers to memory data structures that can potentially be reused by any of the reference allocation services in the VM, once deleted, it is not specified what value the GetObjectRefType
will return.
JDK/JRE 1.6
jboolean IsInstanceOf(JNIEnv *env, jobject obj,
jclass clazz);
Tests whether an object is an instance of a class.
Index 32 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
obj
: a Java object, possibly a NULL
value.
clazz
: a Java class object, must not be NULL
.
Returns JNI_TRUE
if obj
can be cast to clazz
; otherwise, returns JNI_FALSE
. A NULL
object can be cast to any class.
jboolean IsSameObject(JNIEnv *env, jobject ref1,
jobject ref2);
Tests whether two references refer to the same Java object.
Index 24 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
ref1
: a Java object, may be NULL
.
ref2
: a Java object, may be NULL
.
Returns JNI_TRUE
if ref1
and ref2
refer to the same Java object, or are both NULL
; otherwise, returns JNI_FALSE
.
jfieldID GetFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);
Returns the field ID for an instance (nonstatic) field of a class. The field is specified by its name and signature. The Get<type>Field and Set<type>Field families of accessor functions use field IDs to retrieve object fields.
GetFieldID()
causes an uninitialized class to be initialized.
GetFieldID()
cannot be used to obtain the length field of an array. Use GetArrayLength()
instead.
Index 94 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
name
: the field name in a 0-terminated modified UTF-8 string, must not be NULL
.
sig
: the field signature in a 0-terminated modified UTF-8 string, must not be NULL
.
Returns a field ID, or NULL
if the operation fails.
NoSuchFieldError
: if the specified field cannot be found.
ExceptionInInitializerError
: if the class initializer fails due to an exception.
OutOfMemoryError
: if the system runs out of memory.
NativeTypeGet<type>Field(JNIEnv *env, jobject obj,
jfieldID fieldID);
This family of accessor routines returns the value of an instance (nonstatic) field of an object. The field to access is specified by a field ID obtained by calling GetFieldID()
.
The following table describes the Get<type>Field routine name and result type. You should replace type in Get<type>Field with the Java type of the field, or use one of the actual routine names from the table, and replace NativeType with the corresponding native type for that routine.
Get<type>Field Routine Name | Native Type |
---|---|
GetObjectField() | jobject |
GetBooleanField() | jboolean |
GetByteField() | jbyte |
GetCharField() | jchar |
GetShortField() | jshort |
GetIntField() | jint |
GetLongField() | jlong |
GetFloatField() | jfloat |
GetDoubleField() | jdouble |
Indices in the JNIEnv interface function table:
Get<type>Field Routine Name | Index |
---|---|
GetObjectField() | 95 |
GetBooleanField() | 96 |
GetByteField() | 97 |
GetCharField() | 98 |
GetShortField() | 99 |
GetIntField() | 100 |
GetLongField() | 101 |
GetFloatField() | 102 |
GetDoubleField() | 103 |
env
: the JNI interface pointer, must not be NULL
.
obj
: a Java object (, must not be NULL
).
fieldID
: a valid field ID.
Returns the content of the field.
void
Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID,
NativeType
value);
This family of accessor routines sets the value of an instance (nonstatic) field of an object. The field to access is specified by a field ID obtained by calling GetFieldID()
.
The following table describes the Set<type>Field routine name and value type. You should replace type in Set<type>Field with the Java type of the field, or use one of the actual routine names from the table, and replace NativeType with the corresponding native type for that routine.
Set<type>Field Routine | Native Type |
---|---|
SetObjectField() | jobject |
SetBooleanField() | jboolean |
SetByteField() | jbyte |
SetCharField() | jchar |
SetShortField() | jshort |
SetIntField() | jint |
SetLongField() | jlong |
SetFloatField() | jfloat |
SetDoubleField() | jdouble |
Indices in the JNIEnv interface function table.
Set<type>Field Routine | Index |
---|---|
SetObjectField() | 104 |
SetBooleanField() | 105 |
SetByteField() | 106 |
SetCharField() | 107 |
SetShortField() | 108 |
SetIntField() | 109 |
SetLongField() | 110 |
SetFloatField() | 111 |
SetDoubleField() | 112 |
env
: the JNI interface pointer, must not be NULL
.
obj
: a Java object (, must not be NULL
).
fieldID
: a valid field ID.
value
: the new value of the field.
jmethodID GetMethodID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);
Returns the method ID for an instance (nonstatic) method of a class or interface. The method may be defined in one of the clazz
‘s superclassessupertypes and inherited by clazz
. The method is determined by its name and signature.
GetMethodID()
causes an uninitialized class to be initialized.
To obtain the method ID of a constructor, supply <init>
as the method name and void
(V
) as the return type.
Index 33 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
name
: the method name in a 0-terminated modified UTF-8 string, must not be NULL
.
sig
: the method signature in 0-terminated modified UTF-8 string, must not be NULL
.
Returns a method ID, or NULL
if the specified method cannot be found.
NoSuchMethodError
: if the specified method cannot be found.
ExceptionInInitializerError
: if the class initializer fails due to an exception.
OutOfMemoryError
: if the system runs out of memory.
NativeTypeCall<type>Method(JNIEnv *env, jobject obj,
jmethodID methodID, ...);
NativeTypeCall<type>MethodA(JNIEnv *env, jobject obj,
jmethodID methodID, const jvalue *args);
NativeTypeCall<type>MethodV(JNIEnv *env, jobject obj,
jmethodID methodID, va_list args);
Methods from these three families of operations are used to call a Java instance method from a native method.They only differ in their mechanism for passing parameters to the methods that they call.
These families of operations invoke an instance (nonstatic) method on a Java object, according to the specified method ID. The methodID
argument must be obtained by calling GetMethodID
()
.
When these functions are used to call private methods and constructors, the method ID must be derived from the real class of obj
, not from one of its superclasses.
Programmers place all arguments that are to be passed to the method immediately following the methodID
argument. The Call<type>Method routine accepts these arguments and passes them to the Java method that the programmer wishes to invoke.
Programmers place all arguments to the method in an args
array of jvalues
that immediately follows the methodID
argument. The Call<type>MethodA routine accepts the arguments in this array, and, in turn, passes them to the Java method that the programmer wishes to invoke.
Programmers place all arguments to the method in an args
argument of type va_list
that immediately follows the methodID
argument. The Call<type>MethodV routine accepts the arguments, and, in turn, passes them to the Java method that the programmer wishes to invoke.
The following table describes each of the method calling routines according to their result type. You should replace type in Call<type>Method with the Java type of the method you are calling (or use one of the actual method calling routine names from the table) and replace NativeType with the corresponding native type for that routine.
Call<type>Method Routine Name | Native Type |
---|---|
CallVoidMethod() CallVoidMethodA() CallVoidMethodV() | void |
CallObjectMethod() CallObjectMethodA() CallObjectMethodV() | jobject |
CallBooleanMethod() CallBooleanMethodA() CallBooleanMethodV() | jboolean |
CallByteMethod() CallByteMethodA() CallByteMethodV() | jbyte |
CallCharMethod() CallCharMethodA() CallCharMethodV() | jchar |
CallShortMethod() CallShortMethodA() CallShortMethodV() | jshort |
CallIntMethod() CallIntMethodA() CallIntMethodV() | jint |
CallLongMethod() CallLongMethodA() CallLongMethodV() | jlong |
CallFloatMethod() CallFloatMethodA() CallFloatMethodV() | jfloat |
CallDoubleMethod() CallDoubleMethodA() CallDoubleMethodV() | jdouble |
Indices in the JNIEnv interface function table:
Call<type>Method Routine Name | Index |
---|---|
CallVoidMethod() CallVoidMethodA() CallVoidMethodV() |
61 |
CallObjectMethod() CallObjectMethodA() CallObjectMethodV() |
34 |
CallBooleanMethod() CallBooleanMethodA() CallBooleanMethodV() |
37 |
CallByteMethod() CallByteMethodA() CallByteMethodV() |
40 |
CallCharMethod() CallCharMethodA() CallCharMethodV() |
43 |
CallShortMethod() CallShortMethodA() CallShortMethodV() |
46 |
CallIntMethod() CallIntMethodA() CallIntMethodV() |
49 |
CallLongMethod() CallLongMethodA() CallLongMethodV() |
52 |
CallFloatMethod() CallFloatMethodA() CallFloatMethodV() |
55 |
CallDoubleMethod() CallDoubleMethodA() CallDoubleMethodV() |
58 |
env
: the JNI interface pointer, must not be NULL
.
obj
: a Java object, must not be NULL
.
methodID
: a valid method ID.
arguments to the Java method.
args
: an array of arguments.
args
: a va_list of arguments.
Returns the result of calling the Java method.
Exceptions raised during the execution of the Java method.
NativeTypeCallNonvirtual<type>Method(JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, ...);
NativeTypeCallNonvirtual<type>MethodA(JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, const jvalue *args);
NativeTypeCallNonvirtual<type>MethodV(JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, va_list args);
These families of operations invoke an instance (nonstatic) method on a Java object, according to the specified class and method ID. The methodID
argument must be obtained by calling GetMethodID
()
on the class clazz
.
The CallNonvirtual<type>Method families of routines and the Call<type>Method families of routines are different. Call<type>Method routines invoke the method based on the class or interface of the object, while CallNonvirtual<type>Method routines invoke the method based on the class, designated by the clazz
parameter, from which the method ID is obtained. The method ID must be obtained from the real class of the object or from one of its superclassessupertypes.
CallNonvirtual<type>Method routines are the mechanism for invoking "default interface methods" introduced in Java 8.
Programmers place all arguments that are to be passed to the method immediately following the methodID
argument. The CallNonvirtual<type>Method routine accepts these arguments and passes them to the Java method that the programmer wishes to invoke.
Programmers place all arguments to the method in an args
array of jvalues
that immediately follows the methodID
argument. The CallNonvirtual<type>MethodA routine accepts the arguments in this array, and, in turn, passes them to the Java method that the programmer wishes to invoke.
Programmers place all arguments to the method in an args
argument of type va_list
that immediately follows the methodID
argument. The CallNonvirtualMethodV routine accepts the arguments, and, in turn, passes them to the Java method that the programmer wishes to invoke.
The following table describes each of the method calling routines according to their result type. You should replace type in CallNonvirtual<type>Method with the Java type of the method, or use one of the actual method calling routine names from the table, and replace NativeType with the corresponding native type for that routine.
CallNonvirtual<type>Method Routine Name | Native Type |
---|---|
CallNonvirtualVoidMethod() CallNonvirtualVoidMethodA() CallNonvirtualVoidMethodV() | void |
CallNonvirtualObjectMethod() CallNonvirtualObjectMethodA() CallNonvirtualObjectMethodV() | jobject |
CallNonvirtualBooleanMethod() CallNonvirtualBooleanMethodA() CallNonvirtualBooleanMethodV() | jboolean |
CallNonvirtualByteMethod() CallNonvirtualByteMethodA() CallNonvirtualByteMethodV() | jbyte |
CallNonvirtualCharMethod() CallNonvirtualCharMethodA() CallNonvirtualCharMethodV() | jchar |
CallNonvirtualShortMethod() CallNonvirtualShortMethodA() CallNonvirtualShortMethodV() | jshort |
CallNonvirtualIntMethod() CallNonvirtualIntMethodA() CallNonvirtualIntMethodV() | jint |
CallNonvirtualLongMethod() CallNonvirtualLongMethodA() CallNonvirtualLongMethodV() | jlong |
CallNonvirtualFloatMethod() CallNonvirtualFloatMethodA() CallNonvirtualFloatMethodV() | jfloat |
CallNonvirtualDoubleMethod() CallNonvirtualDoubleMethodA() CallNonvirtualDoubleMethodV() | jdouble |
Indices in the JNIEnv interface function table.
CallNonvirtual<type>Method Routine Name | Index |
---|---|
CallNonvirtualVoidMethod() CallNonvirtualVoidMethodA() CallNonvirtualVoidMethodV() | 91 93 92 |
CallNonvirtualObjectMethod() CallNonvirtualObjectMethodA() CallNonvirtualObjectMethodV() | 64 66 65 |
CallNonvirtualBooleanMethod() CallNonvirtualBooleanMethodA() CallNonvirtualBooleanMethodV() | 67 69 68 |
CallNonvirtualByteMethod() CallNonvirtualByteMethodA() CallNonvirtualByteMethodV() | 70 72 71 |
CallNonvirtualCharMethod() CallNonvirtualCharMethodA() CallNonvirtualCharMethodV() | 73 75 74 |
CallNonvirtualShortMethod() CallNonvirtualShortMethodA() CallNonvirtualShortMethodV() | 76 78 77 |
CallNonvirtualIntMethod() CallNonvirtualIntMethodA() CallNonvirtualIntMethodV() | 79 81 80 |
CallNonvirtualLongMethod() CallNonvirtualLongMethodA() CallNonvirtualLongMethodV() | 82 84 83 |
CallNonvirtualFloatMethod() CallNonvirtualFloatMethodA() CallNonvirtualFloatMethodV() | 85 87 86 |
CallNonvirtualDoubleMethod() CallNonvirtualDoubleMethodA() CallNonvirtualDoubleMethodV() | 88 90 89 |
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class, must not be NULL
.
obj
: a Java object, must not be NULL
.
methodID
: a method ID.
arguments to the Java method.
args
: an array of arguments.
args
: a va_list
of arguments.
Returns the result of calling the Java method.
Exceptions raised during the execution of the Java method.
jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);
Returns the field ID for a static field of a class. The field is specified by its name and signature. The GetStatic<type>Field and SetStatic<type>Field families of accessor functions use field IDs to retrieve static fields.
GetStaticFieldID()
causes an uninitialized class to be initialized.
Index 144 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
name
: the static field name in a 0-terminated modified UTF-8 string, must not be NULL
.
sig
: the field signature in a 0-terminated modified UTF-8 string, must not be NULL
.
Returns a field ID, or NULL
if the specified static field cannot be found.
NoSuchFieldError
: if the specified static field cannot be found.
ExceptionInInitializerError
: if the class initializer fails due to an exception.
OutOfMemoryError
: if the system runs out of memory.
NativeTypeGetStatic<type>Field(JNIEnv *env, jclass clazz,
jfieldID fieldID);
This family of accessor routines returns the value of a static field of an object. The field to access is specified by a field ID, which is obtained by calling GetStaticFieldID()
.
The following table describes the family of get routine names and result types. You should replace type in GetStatic<type>Field with the Java type of the field, or one of the actual static field accessor routine names from the table, and replace NativeType with the corresponding native type for that routine.
GetStatic<type>Field Routine Name | Native Type |
---|---|
GetStaticObjectField () | jobject |
GetStaticBooleanField () | jboolean |
GetStaticByteField () | jbyte |
GetStaticCharField () | jchar |
GetStaticShortField () | jshort |
GetStaticIntField () | jint |
GetStaticLongField () | jlong |
GetStaticFloatField () | jfloat |
GetStaticDoubleField () | jdouble |
Indices in the JNIEnv interface function table.
GetStatic<type>Field Routine Name | Index |
---|---|
GetStaticObjectField () | 145 |
GetStaticBooleanField () | 146 |
GetStaticByteField () | 147 |
GetStaticCharField () | 148 |
GetStaticShortField () | 149 |
GetStaticIntField () | 150 |
GetStaticLongField () | 151 |
GetStaticFloatField () | 152 |
GetStaticDoubleField () | 153 |
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
fieldID
: a valid static field ID.
Returns the content of the static field.
void
SetStatic<type>Field(JNIEnv *env, jclass clazz,
NativeType
jfieldID fieldID, value);
This family of accessor routines sets the value of a static field of an object. The field to access is specified by a field ID, which is obtained by calling GetStaticFieldID()
.
The following table describes the set routine name and value types. You should replace type in SetStatic<type>Field with the Java type of the field, or one of the actual set static field routine names from the table, and replace NativeType with the corresponding native type for that routine.
SetStatic<type>Field Routine Name | NativeType |
---|---|
SetStaticObjectField () | jobject |
SetStaticBooleanField () | jboolean |
SetStaticByteField () | jbyte |
SetStaticCharField () | jchar |
SetStaticShortField () | jshort |
SetStaticIntField () | jint |
SetStaticLongField () | jlong |
SetStaticFloatField () | jfloat |
SetStaticDoubleField () | jdouble |
Indices in the JNIEnv interface function table.
SetStatic<type>Field Routine Name | Index |
---|---|
SetStaticObjectField () | 154 |
SetStaticBooleanField () | 155 |
SetStaticByteField () | 156 |
SetStaticCharField () | 157 |
SetStaticShortField () | 158 |
SetStaticIntField () | 159 |
SetStaticLongField () | 160 |
SetStaticFloatField () | 161 |
SetStaticDoubleField () | 162 |
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
fieldID
: a valid static field ID.
value
: the new value of the field.
jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);
Returns the method ID for a static method of a class. The method is specified by its name and signature.
GetStaticMethodID()
causes an uninitialized class to be initialized.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
name
: the static method name in a 0-terminated modified UTF-8 string, must not be NULL
.
sig
: the method signature in a 0-terminated modified UTF-8 string, must not be NULL
.
Returns a method ID, or NULL
if the operation fails.
NoSuchMethodError
: if the specified static method cannot be found.
ExceptionInInitializerError
: if the class initializer fails due to an exception.
OutOfMemoryError
: if the system runs out of memory.
NativeTypeCallStatic<type>Method(JNIEnv *env, jclass clazz,
jmethodID methodID, ...);
NativeTypeCallStatic<type>MethodA(JNIEnv *env, jclass clazz,
jmethodID methodID, jvalue *args);
NativeTypeCallStatic<type>MethodV(JNIEnv *env, jclass clazz,
jmethodID methodID, va_list args);
This family of operations invokes a static method on a Java object, according to the specified method ID. The methodID
argument must be obtained by calling GetStaticMethodID
()
.
The method ID must be derived from clazz
, not from one of its superclasses.
Programmers should place all arguments that are to be passed to the method immediately following the methodID
argument. The CallStatic<type>Method routine accepts these arguments and passes them to the Java method that the programmer wishes to invoke.
Programmers should place all arguments to the method in an args
array of jvalues
that immediately follows the methodID
argument. The CallStaticMethodA routine accepts the arguments in this array, and, in turn, passes them to the Java method that the programmer wishes to invoke.
Programmers should place all arguments to the method in an args
argument of type va_list
that immediately follows the methodID
argument. The CallStaticMethodV routine accepts the arguments, and, in turn, passes them to the Java method that the programmer wishes to invoke.
The following table describes each of the method calling routines according to their result types. You should replace type in CallStatic<type>Method with the Java type of the method, or one of the actual method calling routine names from the table, and replace NativeType with the corresponding native type for that routine.
CallStatic<type>Method Routine Name | Native Type |
---|---|
CallStaticVoidMethod () CallStaticVoidMethodA () CallStaticVoidMethod V() | void |
CallStaticObjectMethod () CallStaticObjectMethod A() CallStaticObjectMethod V() | jobject |
CallStaticBooleanMethod () CallStaticBooleanMethod A() CallStaticBooleanMethod V() | jboolean |
CallStaticByteMethod () CallStaticByteMethod A() CallStaticByteMethod V() | jbyte |
CallStaticCharMethod () CallStaticCharMethod A() CallStaticCharMethod V() | jchar |
CallStaticShortMethod () CallStaticShortMethod A() CallStaticShortMethod V() | jshort |
CallStaticIntMethod () CallStaticIntMethod A() CallStaticIntMethod V() | jint |
CallStaticLongMethod () CallStaticLongMethod A() CallStaticLongMethod V() | jlong |
CallStaticFloatMethod () CallStaticFloatMethod A() CallStaticFloatMethod V() | jfloat |
CallStaticDoubleMethod () CallStaticDoubleMethod A() CallStaticDoubleMethod V() | jdouble |
Indices in the JNIEnv interface function table.
CallStatic<type>Method Routine Name | Index |
---|---|
CallStaticVoidMethod () CallStaticVoidMethodA () CallStaticVoidMethod V() | 141 143 142 |
CallStaticObjectMethod () CallStaticObjectMethod A() CallStaticObjectMethod V() | 114 116 115 |
CallStaticBooleanMethod () CallStaticBooleanMethod A() CallStaticBooleanMethod V() | 117 119 118 |
CallStaticByteMethod () CallStaticByteMethod A() CallStaticByteMethod V() | 120 122 121 |
CallStaticCharMethod () CallStaticCharMethod A() CallStaticCharMethod V() | 123 125 124 |
CallStaticShortMethod () CallStaticShortMethod A() CallStaticShortMethod V() | 126 128 127 |
CallStaticIntMethod () CallStaticIntMethod A() CallStaticIntMethod V() | 129 131 130 |
CallStaticLongMethod () CallStaticLongMethod A() CallStaticLongMethod V() | 132 134 133 |
CallStaticFloatMethod () CallStaticFloatMethod A() CallStaticFloatMethod V() | 135 137 136 |
CallStaticDoubleMethod () CallStaticDoubleMethod A() CallStaticDoubleMethod V() | 138 140 139 |
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
methodID
: a valid static method ID.
arguments to the static method.
args
: an array of arguments.
args
: a va_list
of arguments.
Returns the result of calling the static Java method.
Exceptions raised during the execution of the Java method.
This specification makes no assumptions on how a JVM represent Java strings internally. Strings returned from these operations:
GetStringChars()
GetStringUTFChars()
GetStringRegion()
GetStringUTFRegion()
GetStringCritical()
are
therefore
not
required
to
be
NULL
terminated.
Programmers
are
expected
to
determine
buffer
capacity
requirements
via
GetStringLength()
or
GetStringUTFLength()
.
jstring NewString(JNIEnv *env, const jchar *unicodeChars,
jsize len);
Constructs a new java.lang.String
object from an array of Unicode characters.
env
: the JNI interface pointer, must not be NULL
.
unicodeChars
: pointer to a Unicode string. May be a NULL
value, in which case len
must be 0.
len
: length of the Unicode string. May be 0.
Returns a Java string object, or NULL
if the string cannot be constructed.
OutOfMemoryError
: if the system runs out of memory.
jsize GetStringLength(JNIEnv *env, jstring string);
Returns the length (the count of Unicode characters) of a Java string.
env
: the JNI interface pointer, must not be NULL
.
string
: a Java string object, must not be NULL
.
Returns the length of the Java string.
const jchar * GetStringChars(JNIEnv *env, jstring string,
jboolean *isCopy);
Returns a pointer to the array of Unicode characters of the string. This pointer is valid until ReleaseStringChars()
is called.
If isCopy
is not NULL
, then *isCopy
is set to JNI_TRUE
if a copy is made; or it is set to JNI_FALSE
if no copy is made.
env
: the JNI interface pointer, must not be NULL
.
string
: a Java string object, must not be NULL
.
isCopy
: a pointer to a boolean, may be a NULL
value.
Returns a pointer to a Unicode string, or NULL
if the operation fails.
void ReleaseStringChars(JNIEnv *env, jstring string,
const jchar *chars);
Informs the VM that the native code no longer needs access to chars
. The chars
argument is a pointer obtained from string
using GetStringChars()
.
Index 166 in the JNIEnv interface function table.
env
: the JNI interface pointer,
must
not
be
NULL
.
string
: a Java string object,
must
not
be
NULL
.
chars
: a pointer to a Unicode string,
as
previously
returned
by
GetStringChars()
.
jstring NewStringUTF(JNIEnv *env, const char *bytes);
Constructs a new java.lang.String
object from an array of characters in modified UTF-8 encoding.
env
: the JNI interface pointer, must not be NULL
.
bytes
: the pointer to a modified UTF-8 string, must not be NULL
.
Returns a Java string object, or NULL
if the string cannot be constructed.
OutOfMemoryError
: if the system runs out of memory.
jsize GetStringUTFLength(JNIEnv *env, jstring string);
Returns the length in bytes of the modified UTF-8 representation of a string.
env
: the JNI interface pointer, must not be NULL
.
string
: a Java string object, must not be NULL
.
Returns the UTF-8 length of the string.
const char * GetStringUTFChars(JNIEnv *env, jstring string,
jboolean *isCopy);
Returns a pointer to an array of bytes representing the string in modified UTF-8 encoding. This array is valid until it is released by ReleaseStringUTFChars()
.
If isCopy
is not NULL
, then *isCopy
is set to JNI_TRUE
if a copy is made; or it is set to JNI_FALSE
if no copy is made.
env
: the JNI interface pointer, must not be NULL
.
string
: a Java string object, must not be NULL
.
isCopy
: a pointer to a boolean, may be a NULL
value.
Returns a pointer to a modified UTF-8 string, or NULL
if the operation fails.
void ReleaseStringUTFChars(JNIEnv *env, jstring string,
const char *utf);
Informs the VM that the native code no longer needs access to utf
. The utf
argument is a pointer derived from string
using GetStringUTFChars()
.
env
: the JNI interface pointer, must not be NULL
.
string
: a Java string object, must not be NULL
.
utf
: a pointer to a modified UTF-8 string, previously returned by GetStringUTFChars()
.
Note: In JDK/JRE 1.1, programmers can get primitive array elements in a user-supplied buffer. As of JDK/JRE 1.2 additional set of functions are provided allowing native code to obtain characters in Unicode (UTF-16) or modified UTF-8 encoding in a user-supplied buffer. See the functions below.
void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);
Copies len
number of Unicode characters beginning at
offset start
to the given buffer buf
.
Throws
StringIndexOutOfBoundsException
on
index
overflow.
Index 220 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
str
: a Java string object, must not be NULL
.
start
: the index of the first unicode character in the string to copy. Must be greater than or equal to zero, and less than string length ("GetStringLength()
").
len
: the number of unicode characters to copy. Must be greater than or equal to zero, and "start + len
" must be less than string length ("GetStringLength()
").
buf
: the unicode character buffer into which to copy the string region. Must not be NULL
if given len
is > 0.
StringIndexOutOfBoundsException
: on index overflow.
JDK/JRE 1.2
<void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize len, char *buf);
Translates len
number of Unicode characters beginning at offset start
into modified UTF-8 encoding and place the result in the given buffer buf
.Throws StringIndexOutOfBoundsException
on index overflow
The len
argument specifies the number of unicode characters . The resulting number modified UTF-8 encoding characters may be greater than the given len
argument. GetStringUTFLength()
may be used to determine the maximum size of the required character buffer.
Since this specification does not require the resulting string copy be NULL terminated, it is advisable to clear the given character buffer (e.g. "memset()
") before using this function, in order to safely perform strlen()
.
env
: the JNI interface pointer, must not be NULL
.
str
: a Java string object, must not be NULL
.
start
: the index of the first unicode character in the string to copy. Must be greater than or equal to zero, and less than the string length.
len
: the number of unicode characters to copy. Must be greater than zero, and "start + len
" must be less than string length ("GetStringLength()
").
buf
: the unicode character buffer into which to copy the string region. Must not be NULL
if given len
is > 0.
StringIndexOutOfBoundsException
: on index overflow.
JDK/JRE 1.2
const jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy);
void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);
The semantics of these two functions are similar to the existing Get/ReleaseStringChars
functions. If possible, the VM returns a pointer to string elements; otherwise, a copy is made. However, there are significant restrictions on how these functions can be used. In a code segment enclosed by Get/ReleaseStringCritical
calls, the native code must not issue arbitrary JNI calls, or cause the current thread to block.
The restrictions on Get/ReleaseStringCritical
are similar to those on Get/ReleasePrimitiveArrayCritical
.
JDK/JRE 1.2
jsize GetArrayLength(JNIEnv *env, jarray array);
Returns the number of elements in the array.
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array object, must not be NULL
.
Returns the length of the array.
jobjectArray NewObjectArray(JNIEnv *env, jsize length,
jclass elementClass, jobject initialElement);
Constructs a new array holding objects in class elementClass
. All elements are initially set to initialElement
.
env
: the JNI interface pointer, must not be NULL
.
length
: array size, must be >= 0.
elementClass
: array element class, must not be NULL
.
initialElement
: initialization value, may be a NULL
value.
Returns a Java array object, or NULL
if the array cannot be constructed.
OutOfMemoryError
: if the system runs out of memory.
jobject GetObjectArrayElement(JNIEnv *env,
jobjectArray array, jsize index);
Returns an element of an Object
array.
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array, must not be NULL
.
index
: array index, must be >= 0 and less than array length ("GetArrayLength()
").
Returns a Java object.
ArrayIndexOutOfBoundsException
: if index
does not specify a valid index in the array.
void SetObjectArrayElement(JNIEnv *env, jobjectArray array,
jsize index, jobject value);
Sets an element of an Object
array.
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array, must not be NULL
.
index
: array index, must be >= 0 and less than array length ("GetArrayLength()
").
value
: the new value, may be a NULL
value.
ArrayIndexOutOfBoundsException
: if index
does not specify a valid index in the array.
ArrayStoreException
: if the class of value
is not a subclass of the element class of the array.
ArrayTypeNew<PrimitiveType>Array(JNIEnv *env, jsize length);
A family of operations used to construct a new primitive array object. The following table describes the specific primitive array constructors. You should replace New<PrimitiveType>Array with one of the actual primitive array constructor routine names from this table, and replace ArrayType with the corresponding array type for that routine.
New<PrimitiveType>Array Routines | Array Type |
---|---|
NewBooleanArray() | jbooleanArray |
NewByteArray() | jbyteArray |
NewCharArray() | jcharArray |
NewShortArray() | jshortArray |
NewIntArray() | jintArray |
NewLongArray() | jlongArray |
NewFloatArray() | jfloatArray |
NewDoubleArray() | jdoubleArray |
Indices in the JNIEnv interface function table.
New<PrimitiveType>Array Routines | Index |
---|---|
NewBooleanArray() | 175 |
NewByteArray() | 176 |
NewCharArray() | 177 |
NewShortArray() | 178 |
NewIntArray() | 179 |
NewLongArray() | 180 |
NewFloatArray() | 181 |
NewDoubleArray() | 182 |
env
: the JNI interface pointer, must not be NULL
.
length
: the array length, must be >= 0.
Returns a Java array, or NULL
if the array cannot be constructed.
OutOfMemoryError
: if the system runs out of memory.
NativeType*
Get<PrimitiveType>ArrayElements(JNIEnv *env,
ArrayType
array, jboolean *isCopy);
A family of functions that returns the body of the primitive array. The result is valid until the corresponding Release<
PrimitiveType>
ArrayElements() function is called. Since the returned array may be a copy of the Java array, changes made to the returned array will not necessarily be reflected in the original array
untilRelease<PrimitiveType>ArrayElements()
is called.
If isCopy
is not NULL
, then *isCopy
is set to JNI_TRUE
if a copy is made; or it is set to JNI_FALSE
if no copy is made.
The following table describes the specific primitive array element accessors. You should make the following substitutions:
Regardless of how boolean arrays are represented in the Java VM, GetBooleanArrayElements()
always returns a pointer to jbooleans
, with each byte denoting an element (the unpacked representation). All arrays of other types are guaranteed to be contiguous in memory.
Get<PrimitiveType>ArrayElements Routines | Array Type | Native Type |
---|---|---|
GetBooleanArrayElements() | jbooleanArray | jboolean |
GetByteArrayElements() | jbyteArray | jbyte |
GetCharArrayElements() | jcharArray | jchar |
GetShortArrayElements() | jshortArray | jshort |
GetIntArrayElements() | jintArray | jint |
GetLongArrayElements() | jlongArray | jlong |
GetFloatArrayElements() | jfloatArray | jfloat |
GetDoubleArrayElements() | jdoubleArray | jdouble |
Indices in the JNIEnv interface function table.
Get<PrimitiveType>ArrayElements Routines | Index |
---|---|
GetBooleanArrayElements() | 183 |
GetByteArrayElements() | 184 |
GetCharArrayElements() | 185 |
GetShortArrayElements() | 186 |
GetIntArrayElements() | 187 |
GetLongArrayElements() | 188 |
GetFloatArrayElements() | 189 |
GetDoubleArrayElements() | 190 |
env
: the JNI interface pointer, must not be NULL
.
array
: a Java stringarray object, must not be NULL
.
isCopy
: a pointer to a boolean, may be a NULL
value.
Returns a pointer to the array elements, or NULL
if the operation fails.
OutOfMemoryError
: if the system runs out of memory.
void
Release<PrimitiveType>ArrayElements(JNIEnv *env,
ArrayType
array,
NativeType*elems, jint mode);
A family of functions that informs the VM that the native code no longer needs access to elems
. The elems
argument is a pointer derived from array
using the corresponding Get<
PrimitiveType>
ArrayElements() function. If necessary, this function copies back all changes made to elems
to the original array.
The mode
argument provides information on how the array buffer should be released. mode
has no effect if elems
is not a copy of the elements in array
. Otherwise, mode
has the following impact, as shown in the following table:
mode | actions |
---|---|
0 | copy back the content and free the elems buffer |
JNI_COMMIT | copy back the content but do not free the elems buffer |
JNI_ABORT | free the buffer without copying back the possible changes |
In most cases, programmers pass “0” to the mode
argument to ensure consistent behavior for both pinned and copied arrays. The other options give the programmer more control over memory management and should be used with extreme care.
The next table describes the specific routines that comprise the family of primitive array disposers. You should make the following substitutions:
Release<PrimitiveType>ArrayElements Routines | Array Type | Native Type |
---|---|---|
ReleaseBooleanArrayElements() | jbooleanArray | jboolean |
ReleaseByteArrayElements() | jbyteArray | jbyte |
ReleaseCharArrayElements() | jcharArray | jchar |
ReleaseShortArrayElements() | jshortArray | jshort |
ReleaseIntArrayElements() | jintArray | jint |
ReleaseLongArrayElements() | jlongArray | jlong |
ReleaseFloatArrayElements() | jfloatArray | jfloat |
ReleaseDoubleArrayElements() | jdoubleArray | jdouble |
Indices in the JNIEnv interface function table.
Release<PrimitiveType>ArrayElements Routines | Index |
---|---|
ReleaseBooleanArrayElements() | 191 |
ReleaseByteArrayElements() | 192 |
ReleaseCharArrayElements() | 193 |
ReleaseShortArrayElements() | 194 |
ReleaseIntArrayElements() | 195 |
ReleaseLongArrayElements() | 196 |
ReleaseFloatArrayElements() | 197 |
ReleaseDoubleArrayElements() | 198 |
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array object, must not be NULL
.
elems
: a pointer to array elements, as returned by previous Get<PrimitiveType>ArrayElements
call.
mode
: the release mode: 0
, JNI_COMMIT
or JNI_ABORT
.
voidGet<PrimitiveType>ArrayRegion(JNIEnv *env,
ArrayTypearray,
NativeType
jsize start, jsize len, *buf);
A family of functions that copies a region of a primitive array into a buffer.
The following table describes the specific primitive array element accessors. You should do the following substitutions:
Get<PrimitiveType>ArrayRegion Routine | Array Type | Native Type |
---|---|---|
GetBooleanArrayRegion() | jbooleanArray | jboolean |
GetByteArrayRegion() | jbyteArray | jbyte |
GetCharArrayRegion() | jcharArray | jchar |
GetShortArrayRegion() | jshortArray | jhort |
GetIntArrayRegion() | jintArray | jint |
GetLongArrayRegion() | jlongArray | jlong |
GetFloatArrayRegion() | jfloatArray | jloat |
GetDoubleArrayRegion() | jdoubleArray | jdouble |
Indices in the JNIEnv interface function table.
Get<PrimitiveType>ArrayRegion Routine | Index |
---|---|
GetBooleanArrayRegion() | 199 |
GetByteArrayRegion() | 200 |
GetCharArrayRegion() | 201 |
GetShortArrayRegion() | 202 |
GetIntArrayRegion() | 203 |
GetLongArrayRegion() | 204 |
GetFloatArrayRegion() | 205 |
GetDoubleArrayRegion() | 206 |
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array, must not be NULL
.
start
: the starting index, must be greater than or equal to zero, and less than the array length (GetArrayLength()
).
len
: the number of elements to be copied, must be greater than or equal to zero, and "start + len
" must be less than array length ("GetArrayLength()
").
buf
: the destination buffer, must not be NULL
.
ArrayIndexOutOfBoundsException
: if one of the indexes in the region is not valid.
void
Set<PrimitiveType>ArrayRegion(JNIEnv *env,
ArrayTypearray,
const NativeType
jsize start, jsize len, *buf);
A family of functions that copies back a region of a primitive array from a buffer.
The following table describes the specific primitive array element accessors. You should make the following replacements:
Set<PrimitiveType>ArrayRegion Routine | Array Type | Native Type |
---|---|---|
SetBooleanArrayRegion() | jbooleanArray | jboolean |
SetByteArrayRegion() | jbyteArray | jbyte |
SetCharArrayRegion() | jcharArray | jchar |
SetShortArrayRegion() | jshortArray | jshort |
SetIntArrayRegion() | jintArray | jint |
SetLongArrayRegion() | jlongArray | jlong |
SetFloatArrayRegion() | jfloatArray | jfloat |
SetDoubleArrayRegion() | jdoubleArray | jdouble |
Indices in the JNIEnv interface function table.
Set<PrimitiveType>ArrayRegion Routine | Index |
---|---|
SetBooleanArrayRegion() | 207 |
SetByteArrayRegion() | 208 |
SetCharArrayRegion() | 209 |
SetShortArrayRegion() | 210 |
SetIntArrayRegion() | 211 |
SetLongArrayRegion() | 212 |
SetFloatArrayRegion() | 213 |
SetDoubleArrayRegion() | 214 |
PARAMETERS:
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array, must not be NULL
.
start
: the starting index, must be greater than or equal to zero, and less than the array length (GetArrayLength()
).
len
: the number of elements to be copied, must be greater than or equal to zero, and "start + len
" must be less than array length ("GetArrayLength()
").
buf
: the source buffer, must not be NULL
.
ArrayIndexOutOfBoundsException
: if one of the indexes in the region is not valid.
Note: As of JDK/JRE 1.1, programmers can use New functions introduced as of JDK/JRE 1.3 allow native code to obtain a direct pointer to array elements even if the VM does not support pinning. |
void * GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy);
void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);
The semantics of these two functions are very similar to the existing Get/Release<primitivetype>ArrayElements
functions. If possible, the VM returns a pointer to the primitive array; otherwise, a copy is made. However, there are significant restrictions on how these functions can be used.
After calling GetPrimitiveArrayCritical
, the native code should not run for an extended period of time before it calls ReleasePrimitiveArrayCritical
. We must treat the code inside this pair of functions as running in a "critical region." Inside a critical region, native code must not call other JNI functions, or any system call that may cause the current thread to block and wait for another Java thread. (For example, the current thread must not call read
on a stream being written by another Java thread.)
These restrictions make it more likely that the native code will obtain an uncopied version of the array, even if the VM does not support pinning. For example, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical
.
Multiple pairs of GetPrimtiveArrayCritical
and ReleasePrimitiveArrayCritical
may be nested. For example:
jint len = (*env)->GetArrayLength(env, arr1); jbyte *a1 = (*env)->GetPrimitiveArrayCritical(env, arr1, 0); jbyte *a2 = (*env)->GetPrimitiveArrayCritical(env, arr2, 0); /* We need to check in case the VM tried to make a copy. */ if (a1 == NULL || a2 == NULL) { ... /* out of memory exception thrown */ } memcpy(a1, a2, len); (*env)->ReleasePrimitiveArrayCritical(env, arr2, a2, 0); (*env)->ReleasePrimitiveArrayCritical(env, arr1, a1, 0);
Note that GetPrimitiveArrayCritical
might still make a copy of the array if the VM internally represents arrays in a different format. Therefore we need to check its return value against NULL
for possible out of memory situations.
Linkage Index 222 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array, must not be NULL
.
isCopy
: a pointer to a boolean, may be a NULL
value.
Returns a pointer to the array elements, or NULL if the operation fails.
OutOfMemoryError
: if the system runs out of memory.
JDK/JRE 1.2
Linkage Index 223 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
array
: a Java array, must not be NULL
.
carray
: critical array pointer as returned by GetPrimitiveArrayCritical
.
mode
: the release mode (see Primitive Array Release Modes ): 0
, JNI_COMMIT
or JNI_ABORT
. Ignored if carray
was a not copy.
JDK/JRE 1.2
jint RegisterNatives(JNIEnv *env, jclass clazz,
const JNINativeMethod *methods, jint nMethods);
Registers native methods with the class specified by the clazz
argument. The methods
parameter specifies an array of JNINativeMethod
structures that contain the names, signatures, and function pointers of the native methods. The name
and signature
fields of the JNINativeMethod structure are pointers to modified UTF-8 strings. The nMethods
parameter specifies the number of native methods in the array. The JNINativeMethod
structure is defined as follows:
typedef struct { char *name; char *signature; void *fnPtr; } JNINativeMethod;
The function pointers nominally must have the following signature:
ReturnType (*fnPtr)(JNIEnv *env, jobject objectOrClass, ...);
Index 215 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
methods
: the native methods in the class, must not be NULL
.
nMethods
: the number of native methods in the class, must be greater than zero.
Returns “0” on success; returns a negative value on failure.
NoSuchMethodError
: if a specified method cannot be found or if the method is not native.
jint UnregisterNatives(JNIEnv *env, jclass clazz);
Unregisters native methods of a class. The class goes back to the state before it was linked or registered with its native method functions.
This function should not be used in normal native code. Instead, it provides special programs a way to reload and relink native libraries.
env
: the JNI interface pointer, must not be NULL
.
clazz
: a Java class object, must not be NULL
.
Returns “0” on success; returns a negative value on failure.
jint MonitorEnter(JNIEnv *env, jobject obj);
Enters the monitor associated with the underlying Java object referred to by obj
.
obj
reference must not be NULL
.Each Java object has a monitor associated with it. If the current thread already owns the monitor associated with obj
, it increments a counter in the monitor indicating the number of times this thread has entered the monitor. If the monitor associated with obj
is not owned by any thread, the current thread becomes the owner of the monitor, setting the entry count of this monitor to 1. If another thread already owns the monitor associated with obj
, the current thread waits until the monitor is released, then tries again to gain ownership.
A monitor entered through a MonitorEnter
JNI function call cannot be exited using the monitorexit
Java virtual machine instruction or a synchronized method return. A MonitorEnter
JNI function call and a monitorenter
Java virtual machine instruction may race to enter the monitor associated with the same object.
To avoid deadlocks, a monitor entered through a MonitorEnter
JNI function call must be exited using the MonitorExit
JNI call, unless the DetachCurrentThread
call is used to implicitly release JNI monitors.
env
: the JNI interface pointer, must not be NULL
.
obj
: a normal Java object or class object, must not be NULL
.
Returns “0” on success; returns a negative value on failure.
jint MonitorExit(JNIEnv *env, jobject obj);
The current thread must be the owner of the monitor associated with the underlying Java object referred to by obj
. The thread decrements the counter indicating the number of times it has entered this monitor. If the value of the counter becomes zero, the current thread releases the monitor.
Native code must not use MonitorExit
to exit a monitor entered through a synchronized method or a monitorenter
Java virtual machine instruction.
env
: the JNI interface pointer, must not be NULL
.
obj
: a normal Java object or class object, must not be NULL
.
Returns “0” on success; returns a negative value on failure.
IllegalMonitorStateException
: if the current thread does not own the monitor.
The NIO-related entry points allow native code to access java.nio
direct buffers . The contents of a direct buffer can, potentially, reside in native memory outside of the ordinary garbage-collected heap. For information about direct buffers, please see New I/O APIs and the specification of the java.nio.ByteBuffer class.
Every implementation of the Java virtual machine must support these functions, but not every implementation is required to support JNI access to direct buffers. If a JVM does not support such access then the NewDirectByteBuffer and GetDirectBufferAddress functions must always return NULL, and the GetDirectBufferCapacity function must always return -1. If a JVM does support such access then these three functions must be implemented to return the appropriate values.
jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);
Allocates and returns a direct java.nio.ByteBuffer referring to the block of memory starting at the memory address address and extending capacity bytes.
Native code that calls this function and returns the resulting byte-buffer object to Java-level code should ensure that the buffer refers to a valid region of memory that is accessible for reading and, if appropriate, writing. An attempt to access an invalid memory ___location from Java code will either return an arbitrary value, have no visible effect, or cause an unspecified exception to be thrown.
Index 229 in the JNIEnv interface function table.
env
: the JNIEnvJNI interface pointer, must not be NULL
.
address: the starting address of the memory region (, must not be NULL).
capacity: the size in bytes of the memory region (, must be positive).
Returns a local reference to the newly-instantiated java.nio.ByteBuffer object. Returns NULL if an exception occurs, or if JNI access to direct buffers is not supported by this virtual machine.
OutOfMemoryError: if allocation of the ByteBuffer object fails
JDK/JRE 1.4
void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
Fetches and returns the starting address of the memory region referenced by the given direct java.nio.Buffer.
This function allows native code to access the same memory region that is accessible to Java code via the buffer object.
Index 230 in the JNIEnv interface function table.
env
: the JNIEnvJNI interface pointer, must not be NULL
.
buf: a direct java.nio.Buffer object (, must not be NULL).
Returns the starting address of the memory region referenced by the buffer. Returns NULL if the memory region is undefined, if the given object is not a direct java.nio.Buffer, or if JNI access to direct buffers is not supported by this virtual machine.
JDK/JRE 1.4
jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf);
Fetches and returns the capacity of the memory region referenced by the given direct java.nio.Buffer. The capacity is the number of elements that the memory region contains.
Index 231 in the JNIEnv interface function table.
env
: the JNIEnvJNI interface pointer, must not be NULL
.
buf: a direct java.nio.Buffer object (, must not be NULL).
Returns the capacity of the memory region associated with the buffer. Returns -1 if the given object is not a direct java.nio.Buffer, if the object is an unaligned view buffer and the processor architecture does not support unaligned access, or if JNI access to direct buffers is not supported by this virtual machine.
JDK/JRE 1.4
Programmers can use the JNI to call Java methods or access Java fields if they know the name and type of the methods or fields. The Java Core Reflection API allows programmers to introspect Java classes at runtime. JNI provides a set of conversion functions between field and method IDs used in the JNI to field and method objects used in the Java Core Reflection API.
jmethodID FromReflectedMethod(JNIEnv *env, jobject method);
Converts a java.lang.reflect.Method
or java.lang.reflect.Constructor
object to a method ID.
Index 7 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
method
: a java.lang.reflect.Method
or java.lang.reflect.Constructor
object, must not be NULL
.
A JNI method ID that corresponds to the given Java reflection method, or NULL if the operation fails.
JDK/JRE 1.2
jfieldID FromReflectedField(JNIEnv *env, jobject field);
Converts a java.lang.reflect.Field
to a field ID.
Index 8 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
field
: a java.lang.reflect.Field
object, must not be NULL
.
A JNI field ID that corresponds to the given Java reflection field
, or NULL
if the operation fails.
JDK/JRE 1.2
jobject ToReflectedMethod(JNIEnv *env, jclass cls,
jmethodID methodID, jboolean isStatic);
Converts a method ID derived from cls
to a java.lang.reflect.Method
or java.lang.reflect.Constructor
object. isStatic
must be set to JNI_TRUE
if the method ID refers to a static field, and JNI_FALSE
otherwise.
Throws OutOfMemoryError
and returns 0 if fails.
Index 9 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
cls
: a Java class object, must not be NULL
.
methodID
: a method ID, must not be NULL
.
isStatic
: denotes whether the given methodID
is a static method.
Returns an instance of the java.lang.reflect.Method
or java.lang.reflect.Constructor
which corresponds to the given methodID
, or NULL
if the operation fails.
JDK/JRE 1.2
jobject ToReflectedField(JNIEnv *env, jclass cls,
jfieldID fieldID, jboolean isStatic);
Converts a field ID derived from cls
to a java.lang.reflect.Field
object. isStatic
must be set to JNI_TRUE
if fieldID
refers to a static field, and JNI_FALSE
otherwise.
Throws OutOfMemoryError
and returns 0 if fails.
Index 12 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
cls
: a Java class object, must not be NULL
.
fieldID
: a field ID, must not be NULL
.
isStatic
: denotes whether the given fieldID
is a static field.
Returns an instance of the java.lang.reflect.Field
which corresponds to the given fieldID
, or NULL
if the operation fails.
JDK/JRE 1.2
jint GetJavaVM(JNIEnv *env, JavaVM **vm);
Returns the Java VM interface (used in the Invocation API) associated with the current thread. The result is placed at the ___location pointed to by the second argument, vm
.
Index 219 in the JNIEnv interface function table.
env
: the JNI interface pointer, must not be NULL
.
vm
: a pointer to where the result should be placed, must not be NULL
.
Returns “0” on success; returns a negative value on failure.
The Invocation API allows software vendors to load the Java VM into an arbitrary native application. Vendors can deliver Java-enabled applications without having to link with the Java VM source code.
This chapter begins with an overview of the Invocation API. This is followed by reference pages for all Invocation API functions. It covers the following topics:
The following code example illustrates how to use functions in the Invocation API. In this example, the C++ code creates a Java VM and invokes a static method, called Main.test
. For clarity, we omit error checking.
#include <jni.h> /* where everything is defined */ ... JavaVM *jvm; /* denotes a Java VM */ JNIEnv *env; /* pointer to native method interface */ JavaVMInitArgs vm_args; /* JDK/JRE 69 VM initialization arguments */ JavaVMOption* options = new JavaVMOption[1]; options[0].optionString = "-Djava.class.path=/usr/lib/java"; vm_args.version = JNI_VERSION_1_69; vm_args.nOptions = 1; vm_args.options = options; vm_args.ignoreUnrecognized = false; /* load and initialize a Java VM, return a JNI interface * pointer in env */ JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); delete options; /* invoke the Main.test method using the JNI */ jclass cls = env->FindClass("Main"); jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V"); env->CallStaticVoidMethod(cls, mid, 100); /* We are done. */ jvm->DestroyJavaVM();
This example uses three functions in the API. The Invocation API allows a native application to use the JNI interface pointer to access VM features. The design is similar to Netscape‘s JRI Embedding Interface.
The JNI_CreateJavaVM()
function loads and initializes a Java VM and returns a pointer to the JNI interface pointer. The thread that called JNI_CreateJavaVM()
is considered to be the main thread .
The JNI interface pointer (JNIEnv
) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread()
to attach itself to the VM and obtain a JNI interface pointer. Once attached to the VM, a native thread works just like an ordinary Java thread running inside a native method. The native thread remains attached to the VM until it calls DetachCurrentThread()
to detach itself.
The attached thread should have enough stack space to perform a reasonable amount of work. The allocation of stack space per thread is operating system-specific. For example, using pthreads, the stack size can be specified in the pthread_attr_t
argument to pthread_create
.
A native thread attached to the VM must call DetachCurrentThread()
to detach itself before exiting. A thread cannot detach itself if there are Java methods on the call stack.
The JNI_DestroyJavaVM()
function unloads a Java VM.
The VM waits until the current thread is the only non-daemon user thread before it actually unloads. User threads include both Java threads and attached native threads. This restriction exists because a Java thread or attached native thread may be holding system resources, such as locks, windows, and so on. The VM
cannot automatically free these resources. By restricting the current thread to be the only running thread when the VM is unloaded, the burden of releasing system resources held by arbitrary threads is on the programmer.
A native library may be either dynamically linked or statically linked with the VM. The manner in which the library and VM image are combined is implementation dependent. A System.loadLibrary
or equivalent API must succeed for a library to be considered loaded, this applies to both dynamically and even statically linked libraries.
Once a native library is loaded, it is visible from all class loaders. Therefore two classes in different class loaders may link with the same native method. This leads to two problems:
Each class loader manages its own set of native libraries. The same JNI native library cannot be loaded into more than one class loader. Doing so causes UnsatisfiedLinkError
to be thrown. For example, System.loadLibrary
throws an UnsatisfiedLinkError
when used to load a native library into two class loaders. The benefits of the newthis approach are:
The following rules apply to statically linked libraries, for the statically linked library given in these examples named 'L':
JNI_OnLoad_L
.
JNI_OnLoad_L
and a function called JNI_OnLoad
, the JNI_OnLoad
function will be ignored.
System.loadLibrary("L")
or equivalent API, a JNI_OnLoad_L
function will be invoked with the same arguments and expected return value as specified for the JNI_OnLoad function
.
JNI_OnUnload_L
function of the library if such a function is exported.
JNI_OnUnload_L
and a function called JNI_OnUnload
, the JNI_OnUnload
function will be ignored.
The programmer can also call the JNI function RegisterNatives()
to register the native methods associated with a class. The RegisterNatives()
function is particularly useful with statically linked functions.
If dynamically linked library defines JNI_OnLoad_L
and/or JNI_OnUnload_L
functions, these functions will be ignored.
To facilitate version control and resource management, JNI libraries optionally exportmay define load and unload function hooks. Naming of these of functions depends upon whether the following two functions:library was dynamically or statically linked.
jint JNI_OnLoad(JavaVM *vm, void *reserved);
Optional
function
defined
by
dynamically
linked
libraries.
The VM calls JNI_OnLoad
when the native library is loaded (for example, through System.loadLibrary
).
JNI_OnLoad
must return the JNI version needed by the native library.
In order to make use anyof functions defined at a certain version of the newJNI functions, a native library must export aAPI, JNI_OnLoad
must return a constant defining at least that version. For example, libraries wishing to use AttachCurrentThreadAsDaemon
function that returnsintroduced in JDK 1.4, need to return at least JNI_VERSION_1_24
. If the native library does not export a JNI_OnLoad
function, the VM assumes that the library only requires JNI version JNI_VERSION_1_1
. If the VM does not recognize the version number returned by JNI_OnLoad
, the VM will unload the library and act as if the library was +never loaded.
Exported from dynamically linked native libraries that contain native method implementations.
vm
: a pointer to the current VM structure.
reserved
: unused pointer.
Return the required JNI_VERSION
constant (see also GetVersion
).
void JNI_OnUnload(JavaVM *vm, void *reserved);
Optional function defined by dynamically linked libraries. The VM calls JNI_OnUnload
when the class loader containing the native library is garbage collected.
This function can be used to perform cleanup operations. Because this function is called in an unknown context (such as from a finalizer), the programmer should be conservative on using Java VM services, and refrain from arbitrary Java call-backs.
Exported from dynamically linked native libraries that contain native method implementations.
vm
: a pointer to the current VM structure.
reserved
: unused pointer.
jint JNI_Onload_L<L>(JavaVM *vm, void *reserved);
Mandatory function that must be defined by statically linked libraries .
If a library, named 'L', is statically linked, then upon the first invocation of System.loadLibrary("L")
or equivalent API, a JNI_OnLoad_L
function will be invoked with the same arguments and expected return value as specified for the JNI_OnLoad
function. JNI_OnLoad_L
must return the JNI version needed by the native library. This version must be JNI_VERSION_1_8
or later. If the VM does not recognize the version number returned by JNI_OnLoad_L
, the VM will act as if the library was never loaded.
Exported from statically linked native libraries that contain native method implementation.implementations.
vm
: a pointer to the current VM structure.
reserved
: unused pointer.
Return the required JNI_OnUnloadvoid JNI_OnUnload(JavaVM *vm, void *reservedVERSION
constant (see also GetVersion
);. The VM callsminimum version returned being at least JNI_OnUnload when the class loader containing the native library is garbage collected. This function can be used to perform cleanup operations. Because this function is called in an unknown context (such as from a finalizer), the programmer should be conservative on using Java VM services, and refrain from arbitrary Java call-backs.Note that JNI_OnLoad andVERSION_1_8
.
void JNI_OnUnload_L<L>(JavaVM *vm, void *reserved);
Optional function defined by statically linked libraries. When the class loader containing a statically linked native library 'L' is garbage collected, the VM will invoke the JNI_OnUnload_L
function of the library if such a function is exported.
This function can be used to perform cleanup operations. Because this function is called in an unknown context (such as from a finalizer), the programmer should be conservative on using Java VM services, and refrain from arbitrary Java call-backs.
Exported from statically linked native libraries that contain native method implementations.
vm
: a pointer to the current VM structure.
reserved
: unused pointer.
dlopen
on a UNIX(R) system, does not fully accomplish this goal. A native function is normally called from the Java class loader to perform a call to the host operating system that will load the library into memory and return a handle to the native library. This handle will be stored and used in subsequent searches for native library entry points. The Java native class loader will complete the load process once the handle is successfully returned to register the library. The JavaVM
type is a pointer to the Invocation API function table. The following code example shows this function table.
typedef const struct JNIInvokeInterface *JavaVM; const struct JNIInvokeInterface ... = { NULL, NULL, NULL, DestroyJavaVM, AttachCurrentThread, DetachCurrentThread, GetEnv, AttachCurrentThreadAsDaemon };
Note that three Invocation API functions, JNI_GetDefaultJavaVMInitArgs()
, JNI_GetCreatedJavaVMs()
, and JNI_CreateJavaVM()
, are not part of the JavaVM function table. These functions can be used without a preexisting JavaVM
structure.
jint JNI_GetDefaultJavaVMInitArgs(void *vm_args);
Returns a default configuration for the Java VM. Before calling this function, native code must set the vm_args->version field to the JNI version it expects the VM to support. After this function returns, vm_args->version will be set to the actual JNI version the VM supports.
Exported from the native library that implements the Java virtual machine.
vm_args
: a pointer to a JavaVMInitArgs
structure in to which the default arguments are filled, must not be NULL
.
Returns JNI_OK
if the requested version is supported; returns a JNI error code (a negative number) if the requested version is not supported.
jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs);
Returns all Java VMs that have been created. Pointers to VMs are written in the buffer vmBuf in the order they are created. At most bufLen number of entries will be written. The total number of created VMs is returned in *nVMs.
Creation of multiple VMs in a single process is not supported.
Exported from the native library that implements the Java virtual machine.
vmBuf
: pointer to the buffer where the VM structures will be placed, must not be NULL
.
bufLen
: the length of the buffer.
nVMs
: a pointer to an integer. May be a NULL
value.
Returns JNI_OK
on success; returns a suitable JNI error code (a negative number) on failure.
jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args);
Loads and initializes a Java VM. The current thread becomes the main thread. Sets the env
argument to the JNI interface pointer of the main thread.
The second argument to JNI_CreateJavaVM
is always a pointer to JNIEnv *
, while the third argument is a pointer to a JavaVMInitArgs
structure which uses option strings to encode arbitrary VM start up options:
typedef struct JavaVMInitArgs { jint version; jint nOptions; JavaVMOption *options; jboolean ignoreUnrecognized; } JavaVMInitArgs;
The options
field is an array of the following type:
typedef struct JavaVMOption { /* the option as a string in the default platform encoding */ char *optionString; void *extraInfo; } JavaVMOption;
The size of the array is denoted by the nOptions field in JavaVMInitArgs
. If ignoreUnrecognized
is JNI_TRUE
, JNI_CreateJavaVM
ignore all unrecognized option strings that begin with "-X
" or "_
". If ignoreUnrecognized
is JNI_FALSE
, JNI_CreateJavaVM
returns JNI_ERR
as soon as it encounters any unrecognized option strings. All Java VMs must recognize the following set of standard options:
optionString | meaning |
---|---|
-D<name>=<value> | Set a system property |
-verbose[:class|gc|jni] | Enable verbose output. The options can be followed by a comma-separated list of names indicating what kind of messages will be printed by the VM. For example, "-verbose:gc,class " instructs the VM to print GC and class loading related messages. Standard names include: gc , class , and jni . All nonstandard (VM-specific) names must begin with "X ". |
vfprintf | extraInfo is a pointer to the vfprintf hook. |
exit | extraInfo is a pointer to the exit hook. |
abort | extraInfo is a pointer to the abort hook. |
In addition, each VM implementation may support its own set of non-standard option strings. Non-standard option names must begin with "-X
" or an underscore ("_
"). For example, the JDK/JRE supports -Xms
and -Xmx
options to allow programmers specify the initial and maximum heap size. Options that begin with "-X
" are accessible from the "java
" command line.
Here is the example code that creates a Java VM in the JDK/JRE:
JavaVMInitArgs vm_args; JavaVMOption options[4]; /* disable JIT */ options[0].optionString = "-Djava.compiler=NONE"; /* user classes */ options[1].optionString = "-Djava.class.path=c:\myclasses"; /* set native library path */ options[2].optionString = "-Djava.library.path=c:\mylibs"; /* print JNI-related messages */ options[3].optionString = "-verbose:jni"; vm_args.version = JNI_VERSION_1_2; vm_args.options = options; vm_args.nOptions = 4; vm_args.ignoreUnrecognized = TRUE; /* Note that in the JDK/JRE, there is no longer any need to call * JNI_GetDefaultJavaVMInitArgs. */ res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); if (res < 0) ...
Exported from the native library that implements the Java virtual machine.
p_vm
: pointer to the ___location where the resulting VM structure will be placed, must not be NULL
.
p_env
: pointer to the ___location where the JNI interface pointer for the main thread will be placed, must not be NULL
.
vm_args
: Java VM initialization arguments, must not be NULL
.
Returns JNI_OK
on success; returns a suitable JNI error code (a negative number) on failure.
jint DestroyJavaVM(JavaVM *vm);
Unloads a Java VM and reclaims its resources.
Any thread, whether attached or not, can invoke this function. If the current thread is attached, the VM waits until the current thread is the only non-daemon user-level Java thread. If the current thread is not attached, the VM attaches the current thread and then waits until the current thread is the only non-daemon user-level thread.
Index 3 in the JavaVM interface function table.
vm
: the Java VM that will be destroyed, must not be NULL
.
Returns JNI_OK
on success; returns a suitable JNI error code (a negative number) on failure.
Unloading of the VM is not supported.
jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args);
Attaches the current thread to a Java VM. Returns a JNI interface pointer in the JNIEnv
argument.
Trying to attach a thread that is already attached is a no-op.
A native thread cannot be attached simultaneously to two Java VMs.
When a thread is attached to the VM, the context class loader is the bootstrap loader.
Index 4 in the JavaVM interface function table.
vm
: the VM to which the current thread will be attached, must not be NULL
.
p_env
: pointer to the ___location where the JNI interface pointer of the current thread will be placed, must not be NULL
.
thr_args
: can be NULL or a pointer to a JavaVMAttachArgs
structure to specify additional information:
The second argument to AttachCurrentThread
is always a pointer to JNIEnv
. The third argument to AttachCurrentThread
was reserved, and should be set to NULL
.
You pass a pointer to the following structure to specify additional information:
typedef struct JavaVMAttachArgs { jint version; char *name; /* the name of the thread as a modified UTF-8 string, or NULL */ jobject group; /* global ref of a ThreadGroup object, or NULL */ } JavaVMAttachArgs
Returns JNI_OK
on success; returns a suitable JNI error code (a negative number) on failure.
jint AttachCurrentThreadAsDaemon(JavaVM* vm, void** penv, void* args);
Same semantics as AttachCurrentThread, but the newly-created java.lang.Thread instance is a daemon.
If the thread has already been attached via either AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine simply sets the value pointed to by penv to the JNIEnv of the current thread. In this case neither AttachCurrentThread nor this routine have any effect on the daemon status of the thread.
Index 7 in the JavaVM interface function table.
vm: the virtual machine instance to which the current thread will be attached, must not be NULL
.
penv: a pointer to the ___location in which the JNIEnv interface pointer for the current thread will be placed.
args: a pointer to a JavaVMAttachArgs
structure.
May
be
a
NULL
value.
Returns JNI_OK
on success; returns a suitable JNI error code (a negative number) on failure.
None.
jint DetachCurrentThread(JavaVM *vm);
Detaches the current thread from a Java VM. All Java monitors held by this thread are released. All Java threads waiting for this thread to die are notified.
The main thread can be detached from the VM.Trying to detach a thread that is not attached is a no-op.
If an exception is pending when DetachCurrentThread
is called, the VM may choose to report its existence.
Index 5 in the JavaVM interface function table.
vm
: the VM from which the current thread will be detached,
must
not
be
NULL
.
Returns JNI_OK
on success; returns a suitable JNI error code
(a negative number) on failure.
jint GetEnv(JavaVM *vm, void **env, jint version);
Index 6 in the JavaVM interface function table.
vm
: The virtual machine instance from which the interface
will be retrieved,
must not be NULL
.
env
: pointer to the ___location where the JNI interface pointer for the current thread will be placed, must not be NULL
.
version
: The requested JNI version.
If the current thread is not attached to the VM, sets *env
to NULL
, and returns JNI_EDETACHED
. If the specified
version is not supported, sets *env
to NULL
, and
returns JNI_EVERSION
. Otherwise, sets *env
to the
appropriate interface, and returns JNI_OK
.