Using the Java JNI on OpenVMS

 

This page describes the use of the Java Native Interface on OpenVMS, oriented towards Aida development.

Once we had a Java/CORBA implementation working on VMS, the next step was to be able to call into the SLC control system to complete the CORBA/Java/SLC loop. In addition to the Sun JNI documentation, using the JNI interface to access VMS code is documented in the Compaq Java FAQ with a downloadable example. Read the file JNI_EXAMPLE.COM that comes in the download. It gives you all of the steps to go through and all of the compiler and link options necessary to build a shareable image into which you can call. In outline, here are the steps:

  1. Compile the java file that has the native references with javac.

  2. Generate the header file from the previously compiled file with javah. The fully qualified class name you give as the argument to javah must match the java class name as defined in the .java file exactly, in case and syntax (the argument must include the whole package name). So you must run javah from the root directory of the package; ie, for the slc subpackage of the edu.stanford.slac.aida package suite, this means make the current directory the directory in which [.edu.stanford.slac.aida.slc] is a subdirectory, then run javah. To run javah on VMS you need to put the name of the class in doublequotes. For example, for the in the edu.stanford.slac.aida.slc package, the SlcI_impl class makes use of some native routines, so we run a javah command of the form:

    javah -jni "edu.stanford.slac.aida.slc.SlcI_impl" 

  3. Create or modify the .c code files to 

    1. #include the .h file created by the javah compiler from the step above in the .c file which defines the functions prototyped by that include file.

    2. Define the functions prototyped by the javah compiler from the step above.

  4. Compile all of your native code (C in my case) using all the switches required by JNI_EXAMPLE.COM (these should be reflected in the .COM file below). 

  5. Link the shareable using all the indicated options (see .COM file below).

    Note that the generated JNI* routines are case sensitive. Thus to call into one of our shareables from the JNI* routine you either have to uppercase all of our routine names or make a separate helper file that you can compile with our normal switches. 

    Note also that symbol names longer than 31 chars are automatically shortened by the javac and javah compiler down to 31 characters (on all platforms, including VMS). Care must be taken to compile the .c source code implementing the JNI routines with the correct qualifier to make sure the C compiler produces the same shortened symbol name. On VMS the "/name" qualifier is used (/name=(shortened, as_is). Also, to get the correct shortened names in the linker options file use Compaq's SCAN_GLOBALS_FOR_OPTION.COM to build a .OPT file which correctly defines the UNIVERSAL symbols when linking the shareable. For some reason this .COM file does not produce a .OPT file if one of the required name already exists, so if you change a symbol name be sure to delete the existing .OPT file before re-running this .COM file to produce a new one. 

  6. Define a logical name that points to the shareable. This is what you use in the System.loadLibrary call in your java implementation.  That's it!

.COM and .OPT files

Here's a .com file and associated options files to compile the source and build the shareable. this performs steps 4 and 5 above.

$! Build shareable C library for Java interface
$ opts = "/prefix=all /float=ieee /ieee=denorm /define=JIT_OPTION " + -
         "/names=(shortened,as_is) /reentrancy=multithread"
$ INCL = "/include=sys$common:[java$122.include...]"
$ cc/lis 'opts'  'INCL' db_java.c
$ cc/debug db_java_helper.c
$!
$!
$! Global option file
$ GLB_OPT:= global_symbol_option
$ LIB_OPT:= library_option
$ @scan_globals_for_option *.obj 'GLB_OPT'.opt
$
$! link native shareable
$!
$ link /map/debug/SHARE=CorbaDBShr.exe -
 global_symbol_option /OPT, library_option /OPT, slcopt:slc_common/opt
$!
Run this simply as:
MCCDEV> @BUILDCLIB.COM

Example output of SCAN_GLOBALS_FOR_OPTION.COM

MCCDEV> typ GLOBAL_SYMBOL_OPTION.OPT;1
case_sensitive=YES
SYMBOL_VECTOR=(Java_edu_stanford_slac_1v09lg4$=PROCEDURE,-
Java_edu_stanford_slac_11pr094$=PROCEDURE,-
Java_edu_stanford_slac_0mqusd0$=PROCEDURE)
case_sensitive=NO
case_sensitive=YES
SYMBOL_VECTOR=(MYDB_INIT=PROCEDURE,-
MY_DBGET=PROCEDURE)
case_sensitive=NO

Options file to link to SLC Control System Libraries

You need to write this by hand

MCCDEV> typ library_option.opt
db_java.obj, db_java_helper.obj, -
SLCLIBS:SLCLIB.OLB/inc=(STANDALONE_INIT), -
SLCLIBS:SLCLIB.OLB/inc=(STND_HELP), -
SLCLIBS:SLCLIB.OLB/inc=(STNDINIT_EXIT_HANDLER)
!
JAVA$JAVA_G_SHR/SHARE
DBSSHR/shareable
IOBSIC/shareable
CRRUTIL/shareable
SYSUTIL/shareable
UTILSHR/shareable

Have fun.


[Aida Home Page][SLAC Controls Software Group][ SLAC Home Page]

Author  Robert C. Sass
Modifed by: Greg White, 19-Jul-2001 Added help for long package; reformated.