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.