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:
Compile the java file that has the native references with javac.
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"
Create or modify the .c code files to
#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.
Define the functions prototyped by the javah compiler from the step above.
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).
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.
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!
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
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
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.