JNI considerations

If you use JNI from native code on a 64-bit system, you must ensure that length-related quantities in JNI are defined as 64 bit.

You must ensure that length-related quantities in JNI are defined as 64 bit even though the underlying objects and quantities within the Java™ Developer Kit (JDK) are restricted to values no greater than 31 bit. An error occurs if native code uses values greater than 31 bit for these quantities.

The definition of JNI is held in two header files (jni.h and jni_md.h), which are included by any native code that uses JNI.

In a 64-bit version of the JDK, the JNI interface itself changes as follows:

Pointers (foo *)
All pointers become 64 bit.
<jni_md.h> jint
This is defined as a 31-bit value (int), since on Unix systems a long is a 64-bit integer.
<jni.h> jsize
This type is used extensively for quantities that imply lengths. This is changed on 64-bit systems to a jlong so that it is 64 bits, in contrast to the definition on 31-bit systems where it is a jint, which is 31 bits.
jfloat, jdouble
Values remain the same as in 31-bit systems.
jobject
Defined as a pointer and so is 64 bit.
jclass, jthrowable, jstring, jarray
All declared as jobject and are all 64 bit.
jvalue
A union of all basic 'j' types and is already 64 bit.
jmethodID, jfieldID
Declared as pointer types and are 64-bit quantities.
JNINativeMethod
struct is 3 pointers and becomes 24 bytes.
JNIEnv
Declared as a pointer type and is 64 bit.
JavaVM
Declared as a pointer type and is 64 bit.
JNINativeInterface
Declared as an array of 64-bit pointers.
DefineClass
Has a buffer parameter with an associated size parameter. The size parameter is declared as a jsize and therefore is a 64-bit integer length. However, class objects cannot be this large, so there is an upper bound to the value of the size parameter and is less than 31 bits.
PushLocalFrame
Has a capacity defined by a jint and is limited to 31 bits.
EnsureLocalCapacity
Has a capacity defined by a jint and is limited to 31 bits.
NewString
Has a jsize length parameter and becomes 64 bit. However, the size of the supplied unicode string has a maximum length no greater than a 31-bit integer.
GetStringLength
Returns a jsize, which is 64 bit. The length of a Java string is limited to 31-bit integer values.
GetStringUTFLength
Returns a jsize, which is 64 bit. The length of a Java string is limited to 31-bit integer values.
GetArrayLength
Returns a jsize, which is 64 bit. However, Java arrays cannot have a length greater than a 31-bit integer value.
NewXxxArray
(where Xxx is the type of a primitive: for example, NewBooleanArray.) All have jsize length parameters, which are 64 bit. Java arrays cannot have a length greater than a 31-bit integer value.
GetObjectArrayElement, SetObjectArrayElement
Both have jsize index values which are 64 bit. Java arrays cannot have a length greater than a 31-bit integer.
GetXxxArrayRegion, SetXxxArrayRegion
(where Xxx is the type of a primitive: for example, GetIntArrayRegion, SetFloatArrayRegion.) All have jsize start and length fields, which are 64 bit. Java arrays cannot have a length greater than 31-bit integer value.
RegisterNatives
Has a jint parameter - number of methods.
GetStringRegion, GetStringUTFRegion
Both have start and length parameters as jsize, which are 64 bit. Strings are limited to 31-bit lengths.
JavaVMOption
struct has two pointers: both become 64 bit.
JavaVMInitArgs
The alignment of this struct is affected by change to JavaVMOption struct.
JavaVMAttachArgs
Alignment is affected by two pointers.