
Using 31-bit native C or C++ code with the 64-bit Java VM (z/OS only)
From service refresh 6, fix pack 35, you can recompile your native 31-bit C or C++ code and use it with a Java™ application running on a 64-bit Java virtual machine (VM). This feature makes it easier for you to migrate Java applications that use native code from the 31-bit SDK to the 64-bit SDK, with minimal changes to the native code.
Before you begin
This feature requires APAR PH28966 on z/OS® 2.3 or later.
null
. To create a direct buffer
and ensure that the native buffer memory is in the 31-bit range, you might have to modify your C or
C++ code as follows:- Allocate the 31-bit memory by using the appropriate function. If the C or C++ code will run in AMODE 31, use the malloc() function to allocate the memory. If the C or C++ code will run in AMODE 64, use the __malloc31() function to request memory in the 31-bit range.
- Create the Java direct byte buffer that references this
31-bit memory by passing the buffer in the address parameter of the
NewDirectByteBuffer()
function:
For more information about this function, see the Oracle JNI documentation.jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);
- Track the resulting ByteBuffer object. When the object is no longer used by any Java methods, free the native buffer memory. This step is required because the JVM does not free the native buffer memory when it processes the ByteBuffer object during garbage collection.
About this task
You might want to migrate your Java applications to the 64-bit version of IBM® SDK, Java Technology Edition to take advantage of the increased amount of virtual storage (limited to 2GB in the 31-bit SDK). Usually, Java applications that run 31-bit native code can run only with a 31-bit SDK; mixing 31-bit code and 64-bit code in the same process space is challenging because of the incompatibility of the pointer sizes and memory addressability between these two types of code.
With APAR PH28966 on z/OS 2.3 and later, z/OS Language Environment® (LE) provides the capability to run AMODE 31 programs and AMODE 64 programs in the same address space. Separate LE environments are established for each addressing mode (AMODE). The IBM SDK takes advantage of this capability to simplify the migration of Java applications that use 31-bit native code to the 64-bit SDK. The Invocation and JNI APIs in the 64-bit SDK allow 31-bit native code to compile, link, and inter-operate with the 64-bit SDK. The 64-bit VM also supports the loading and invocation of 31-bit native libraries and functions.
- A 31-bit compatible set of C/C++ JNI header files, which contain JNI data and argument types to
support Invocation and JNI APIs. These files are in the javahome/include31
directory, where
javahome is the JAVA_HOME path of your IBM SDK installation. JNI types that represent object references
and other VM constructs, like
jobject
,jarray
,jclass
,jmethodID
, andjfieldID
, are updated to be 64-bit representations.Note: Because the C language does not provide a way to define a 64-bitpointer
type in a 31-bit application, a primitive 64-bitlong long
data type is used instead. This might lead to compiler warnings for code that assigns or compares JNI object references withNULL
. You might need to update the code to assign or compare with0
instead. - A 31-bit shared library, libjvm31.so, with a matching libjvm31.x side-deck file to enable 31-bit native code to link and resolve the Invocation and JNI APIs.
- Recompile any C or C++ native code that references JNI constructs against the include/jni31 set of JNI header files, and link against the libjvm31.so library.
- Run your Java application with the 64-bit SDK, specifying
the
-XX:+Enable3164Interoperability
VM option.
- The 31-bit native application must be a single-thread. The 64-bit Java application can be multi-threaded but only a single Java application thread is allowed to inter-operate across the AMODE boundary. If a second application thread tries to load a 31-bit library or call a 31-bit C or C++ function, a java.lang.UnsatisfiedLinkError is usually thrown.
- You must compile the 31-bit native application with standard CALL linkage; XPLINK is not supported.
- LE Condition handling support is not available across the AMODE boundary. Specifically,
-XCEEHDLR
,-Xsignal:userConditionHandler=percolate
, and related options are not supported. LE conditions are not converted into Java exceptions. - Signal chaining is not supported across the AMODE boundary.
- Environment variables are copied across the AMODE boundary on the first transition only. Subsequent updates in one AMODE environment are not propagated back to the other; instead, the variables are tracked separately in each AMODE environment. For more information, see Environment variables propagation to secondary Language Environment in Introduction to AMODE 31 and AMODE 64 programs interoperability.
Procedure
Results
-XX:+Enable3164Interoperability
option on the command line or in the
JNI_CreateJavaVM API when you ran your
application:An AMODE64 application is attempting to load an AMODE31 DLL load module.
