Example of using shared libraries on z/OS
This example describes the process of using native shared libraries with a Java™ application on z/OS systems.
About this task
This task demonstrates how to create a Java application that loads and invokes C functions within a native shared library.
Procedure
-
Create a sample application Sample.java:
public class Sample { /** * A static class initialization block that is run when this class * is first loaded. Here, try to load the target libSample.so shared library * that implements the printFromNative() method declared later. */ static { try { System.loadLibrary("Sample"); } catch (Throwable e) { throw new RuntimeException(e); } } /** * Prints a message to STDOUT. * The 'native' keyword indicates that this method is implemented in native code, * callable through the Java Native Interface (JNI). */ public static native void printFromNative(); public static void main(String[] args) { // Invoke the native method Sample.printFromNative(); } }
This Java application declares a static native method
During the static class initialization block that is run when theSample.printFromNative()
, and calls this native method from themain
method.Sample
class is first loaded, theSystem.loadLibrary("Sample")
call loads the target native librarylibSample.so
.Note: TheSystem.loadLibrary(libname)
API adds the prefixlib
and the suffix.so
to the library name that you provide. The SDK searches for the target shared library within the library path that is specified in theLIBPATH
environment variable. If your target native shared library is an MVS data set, or you have a specific absolute path or library name, use theSystem.load(filename)
API instead. -
The Java portion of the application is complete, so you
can now compile it:
javac Sample.java
-
Use the javac -h command to create a header file for the native code:
This command generates a C header file that is calledjavac -h . Sample.java
Sample.h
, with the appropriate JNI method signatures for your native application implementation. -
Create a file called
Sample.c
:
This file provides the C native implementation of the Java#include <stdio.h> #include "Sample.h" JNIEXPORT void JNICALL Java_Sample_printFromNative(JNIEnv * env, jclass cls) { printf( "Printing from native\n" ); }
Sample.printFromNative()
method. -
Compile
Sample.c
, link, and bind it into a shared librarylibSample.so
, that can be loaded and called dynamically from a Java application. You can use either XL C/C++ or Open XL C/C++ compiler.
XL C/C++ commandFor example:xlc -q64 -W "l,dll" -W "c,langlvl(extended),float(ieee),dll,exportall" -o libSample.so -I$JAVA_HOME/include -I$JAVA_HOME/include/zos Sample.c $JAVA_HOME/lib/j9vm/libjvm.x
where
$JAVA_HOME
is the JAVA_HOME path of your IBM SDK installation. The header file jni.h exists under $JAVA_HOME/include and libjvm.x is in $JAVA_HOME/lib/j9vm.TheXL C/C++
specific elements in the compile and link commands are as follows:Table 1. XL C/C++ command specific elements Option Description xlc The command that runs the XL C compiler. -q64 Option valid for 64-bit only. Tells the compiler to compile the target shared library for AMODE64 platforms. -W "l,dll" The option -W
is passed to the link phase of the compiler. The linker creates a shared library .so file.-W "c,langlvl(extended), float(ieee),dll,exportall"The option -W
is passed to the compile phase of the compiler.langlvl(extended)
enables language extensions that are used by the JNI header files, such aslong long
.float(ieee)
tells the compiler to generate binary IEEE754 floating-point numbers and instructions, which match thefloat
anddouble
primitive types of the Java language.dll
tells the compiler to produce DLL code. The DLL code can export or import functions and external variables.exportall
specifies that call functions in the shared library are callable by external programs.
Open XL C/C++ commandFor example:ibm-clang -m64 -fvisibility=default -o libSample.so -I$JAVA_HOME/include -I$JAVA_HOME/include/zos Sample.c $JAVA_HOME/lib/j9vm/libjvm.x
where $JAVA_HOME is the JAVA_HOME path of your IBM SDK installation.
TheOpen XL C/C++
specific elements in the compile and link commands are as follows:Table 2. Open XL C/C++ command specific elements Option Description ibm-clang The command that runs the Open XL C compiler. -m64 Tells the compiler to compile the target shared library for AMODE64 platforms. 64-bit only. -fvisibility=default This option exports all externally defined functions and variables in the compilation unit so that a DLL application can use them. The remaining shared elements in the compile and link commands are as follows:Table 3. Common elements for XL and Open XL Option Description -o libSample.so The output file, which is the shared library that you want to build. The name (the text between lib
and.so
) must match the name that you provided to theSystem.load(filename)
orSystem.loadLibrary(filename)
Java APIs.-I$JAVA_HOME/include Tells the compiler to look in the $JAVA_HOME /include directory, in addition to the default directories, for header files (in this case, JNI header files). Change $JAVA_HOME to be the JAVA_HOME path of your IBM SDK installation. -I$JAVA_HOME/include/zos Tells the compiler to look in the $JAVA_HOME /include/zos directory, in addition to the default directories, for header files (in this case, JNI header files). Sample.c Your C program. $JAVA_HOME/lib/j9vm/libjvm.x The sidedeck file that enables native code to link and resolve the JNI and Invocation APIs. -
Run the
Sample
application.Because you used theSystem.loadLibrary
Java API to specify the target shared library, you must make sure that either theLIBPATH
environment variable or thejava.library.path
property includes the directory where thelibSample.so
library resides.For example:
orLIBPATH=. java Sample
java -Djava.library.path=. Sample
The program outputs the following message:Printing from native
Results
Now, you are able to use the same framework to access native shared libraries from Java applications.