Revision/Update Information: This is a new manual.
Operating System and Version: OpenVMS Alpha Version 7.3-2
OpenVMS I64 Version 8.2
Software Version: J2VMS Version 1.3
Java for OpenVMS Version 1.2 or higher
OpenVMS is a trademark of Hewlett-Packard Development Company. L.P.
Java is a trademark of Sun Microsystems. Inc.
Contents |
This manual attempts to describe, as completely as possible, the J2VMS calling interface.
This manual is designed for programmers who are developing Java applications that must communicate directly with OpenVMS System Services and Run-Time Libraries (including customer libraries).
It is expected that readers will have a working knowledge of software design and development. It is encouraged that the reader also explore some of the Java documentation pointers included below.
This manual contains the following chapters
The following documents may be useful when using J2VMS.
Java2
1.3.1 SE API Specification
HP OpenVMS RTL Library (LIB$)
Manual: LIB$FIND_IMAGE_SYMBOL
J2VMS V1.3 API
Specification
Optimizing Java Technology Software
Performance on HP OpenVMS.
BLISS Language Reference
Manual
Guide to HP Structure Definition Language
A collection of examples programs are present on line in SYS$COMMON:[SYSHLP.EXAMPLES.J2VMS]. (This device-directory specification may have been given the logical name J2VMS$EXAMPLES during installation of the J2VMS software kit.)
Kednos welcomes your comments on this manual. Please send any comments, corrections, etc. to either of the following addresses:
pli-support@kednos.com | |
Postal Mail |
Kednos Enterprises
Suite 7, 220 Country Club Drive Pacific Grove, CA 93950 |
This section contains release information on J2VMS. Release information is necessary for gaining the best results from J2VMS. It is recommended that all users read this information.
J2VMS Version 1.3 contains the following enchancements and fixes:
J2VMS Version 1.3 contains the following restrictions:
This chapter covers the installation and removal of J2VMS including
software and hardware dependencies.
1.1 Software Prerequisites
The following software is required to successfully install and use J2VMS:
It is also recommended that all available software patches be applied to these products prior to attempting installation.
For improved performance later versions of the JDK are also
recommended. Later versions include support for FastVM and other
significant performance improvements.
1.2 Hardware Requirements
The only hardware requirement is that the system be either an Alpha or Integrity system as J2VMS (like Java) is only available on OpenVMS Alpha and I64.
Be aware that Java is particullarly resource hungry so older, slower
machines will often perform poorly, particularly in interactive
environments. The general rule of thumb is, the more memory and the
faster the CPU the better Java applications will perform. There are
some documents available that offer hints and tips for performance
improvements. Details of these can be found under the section
Associated Documents.
1.3 Installation
The J2VMS software product kit presents a number of options to the installer to control exactly what is installed. Table 1-1 describes each of these options and their defaults. Example 1-1 shows an example of an installation of the J2VMS product.
Description | Default |
---|---|
User Guide & Release Notes in PostScript format | Yes |
User Guide & Release Notes in PDF format | Yes |
User Guide & Release Notes in HTML format | Yes |
J2VMS API Specification | Yes |
Example programs | Yes |
Example 1-1 J2VMS Product Installation |
---|
$ PRODUCT INSTALL J2VMS The following product has been selected: KEDNOS VMS J2VMS V1.3 Layered Product Do you want to continue? [YES] YES Configuration phase starting ... You will be asked to choose options, if any, for each selected product and for any products that may be installed to satisfy software dependency requirements. KEDNOS VMS J2VMS V1.3: Java Interface to Native OpenVMS Copyright © 2001-2002 Jim Brankin, 2008 Kednos Enterprises Kednos Enterprises This product uses the PAK: J2VMS Do you want the defaults for all options? [YES] NO Install J2VMS Documentation? [YES] YES Do you want the defaults for all suboptions? [YES] NO Install the J2VMS V1.3 API Specification [YES] YES Install J2VMS User Guide & Release Notes in HTML format? [YES] YES Install J2VMS User Guide & Release Notes in PDF format? [YES] YES Install J2VMS User Guide & Release Notes in PostScript format? [YES] YES Install example programs? [YES] YES Do you want to review the options? [NO] NO Execution phase starting ... The following product will be installed to destination: KEDNOS VMS J2VMS V1.3 DISK$AXP082:[VMS$COMMON.] Portion done: 0%...10%...20%...30%...70%...90%...100% The following product has been installed: KEDNOS VMS J2VMS V1.3 Layered Product KEDNOS VMS J2VMS V1.3: Java Interface to Native OpenVMS Relase Notes are included in the user guide. J2VMS release notes are included in the User Guide & Release Notes manual. To install these locally ensure that at least one documentation option is selected. Otherwise, the manual can be found at the Kednos website. Insert the following lines in SYS$MANAGER:SYSTARTUP_VMS.COM: @SYS$STARTUP:J2VMS$STARTUP.COM |
Once the J2VMS software product kit has been installed it is advisable
to add the startup procedure, SYS$STARTUP:J2VMS$STARTUP.COM to the
system startup prodcedure. Althought it is not necessary in this kit,
it may become so in a later release. It als defines the J2VMS$EXAMPLES
logical and installs the SYS$LIBRARY:J2VMS$SHR.EXE image.
1.5 Removal
Removal of the software product is a case of using the PCSI PRODUCT REMOVE command. There is no provision in this release for clean up of the API Specification in this kit (it is expected this will change in a future release). If the API spec was unpacked it will have to be removed manually.
Example 1-2 demonstrates removal of the J2VMS product.
Example 1-2 J2VMS Product Removal |
---|
$ PRODUCT REMOVE J2VMS The following product has been selected: KEDNOS VMS J2VMS V1.3 Layered Product Do you want to continue? [YES] YES The following product will be removed from destination: KEDNOS VMS J2VMS V1.3 DISK$AXP082:[VMS$COMMON.] Portion done: 0%...40%...50%...60%...70%...80%...100% The following product has been removed: KEDNOS VMS J2VMS V1.3 Layered Product |
This chapter covers the different parts of the J2VMS interface and how
It has been deliberately written to draw comparisons between native
coding and coding in Java using J2VMS. The intention is that it will be
easier to understand for someone who has more background in native
languages such as PL/I, BASIC, C and Pascal.
2.1 Includes
The first item to cover is how to make the J2VMS interface available to a Java program. It is quite simple and is tackled in two steps. The first is configuring the Java classpath. Without this the Java compiler and interpreter will not be able to find the J2VMS classes. The example below demonstrates how to include that J2VMS library in the JAVA$CLASSPATCH logical.
$ DEFINE JAVA$CLASSPATH SYS$LIBRARY:J2VMS$VS.JAR |
Another way to configure the Java classpath is to include it on the command line as shown in this example:
$ java -classpath "/sys$library/j2vms$vs.jar:..." ... |
For more information on configuring the Java classpath, please consult the relevant Java for OpenVMS user guide.
Once the compiler and interpreter can find the J2VMS class library the relevant classes need to be included in the source module. It is recommended that the base vs package be included in it's entirety. It it not normally recommended to include external packages in this way. However, the vs package is not made up of many classes.
When it comes to including the different modules within STARLET it is best to only include those classes that are necessary. There are many modules in the vs.starlet package. This will cause unnecessary memory usage and increase compile and load time significantly.
The example below demonstrates the best way to include the vs package and the STARLET modules SS and STS.
import vs.*; import vs.starlet.SS; import vs.starlet.STS; |
In order for J2VMS to call native routines they first need to be declared. This can be likened to declaring a routine in C with the extern attribute or declaring an external entry in PL/I. The difference in Java is that there is no linker to process the external declarations and locate the relevant shared image. Therefore the caller needs to know which shareable image the routines exists in.
The external declaration is constructed using the SystemCall. class. This class is a simplified method for calling the LIB$ Run-Time Library routine LIB$FIND_IMAGE_SYMBOL (sometimes referred to as LIB$FIS). LIB$FIND_IMAGE_SYMBOL dynamically loads shareable images by looking up symbols.
The following example below demonstrates how to declare the external routine LIB$PUT_OUTPUT (found in SYS$LIBRARY:LIBRTL.EXE) in Java. It also includes examples in C, PL/I and BASIC for comparison.
#1 |
---|
SystemCall lib$put_output = new SystemCall("LIB$PUT_OUTPUT", "LIBRTL"); |
The same declaration in C
#2 |
---|
extern int lib$put_output(); |
The same declaration in PL/I
#3 |
---|
declare lib$put_output entry(any, any) returns(fixed binary(31)); |
The same declaration in BASIC
#4 |
---|
external integer function lib$put_output |
The Structure Definition Language (SDL) can be used to generate
external routine declarations also. These classes can then be used in
the same way as the classes vs.SystemServices and
vs.LibRoutines. These classes are covered further in
Section 2.4.
2.3 Argument Passing Mechanisms
Before discussing the actual call mechanism between J2VMS and native OpenVMS it is important to first cover argument passing. J2VMS provides a set of classes that allow the caller to pass arguments in the common language environment, just as they would a native language. These classes are:
Passing arguments using J2VMS can be likened to constructing an argument list for the LIB$ Run-Time Library function LIB$CALLG. An array of pointers and/or values is constructed and passed to the target routine using LIB$CALLG as a catalyst (originally high level language access to the VAX CALLG instruction). J2VMS is quite similar. However, it has it's minor differences mostly related to the object oriented architecture of Java.
J2VMS argument lists are constructed as an array of objects from the abstract class vs.VMSparam. Unlike an argument list destined for LIB$CALLG there is no need for the argument count in the first element as the size of the array is known, thanks to Java. This means that all elements in the argument list detail arguments. Each element consists of an argument mechanism class (shown above) that informs J2VMS as to exactly how it's own argument is to be passed. When J2VMS actually performs the call it determines the mechanism by comparing class types and then allocating internal storage as necessary. Copying between internal storage and Java class storage before and after the actual native call.
#1 |
---|
StringBuffer result = new StringBuffer(); Byte code = new Byte((byte) 65); vs.VMSparam arglst = new VMSparam[] { new ByDesc(result), new ByRef(code) }; |
The LIB$ Run-Time Library routine LIB$CHAR accepts two arguments. The first is a result string, passed by descriptor, and the second is a byte containing an 8-bit ASCII character code.
#2 |
---|
declare arglst(2) pointer; declare 1 result, 2 dsc$w_length fixed binary(15), 2 dsc$b_dtype fixed binary(7), 2 dsc$b_class fixed binary(7), 2 dsc$a_pointer pointer; declare result_str character(dsc$w_length) based(dsc$a_pointer); declare code fixed binary(7); result.dsc$w_length = 0; result.dsc$b_dtype = DSC$K_DTYPE_T; result.dsc$b_class = DSC$K_CLASS_D; result.dsc$a_pointer = null(); arglst(1) = addr(result); arglst(2) = addr(code); |
The above snippet of PL/I code attempts to demonstrate the actions of the code above in a native language. In this example the string descriptor for result is constructed explictly to show what J2VMS does internally when dealing with an argument passed by descriptor.
The following sections cover each of the mechanisms in close. These
sections must be read carefully as there are one or two caveats that
must be observed. For full documentation of what data types each
passing mechanism class can deal with, please consult the J2VMS API
Specification. This documentation ships with the software product and
is available at the Kednos website. See Associated Documents for more details.
2.3.1 Passing Arguments By Descriptor
The class vs.ByDesc is used to inform J2VMS that it's argument should be passed by descriptor. Many data types can be passed by descriptor. However, probably the most used are vs.Cmem, java.lang.StringBuffer and byte[]. Both vs.Cmem and byte[] result in fixed length descriptors of type DSC$K_CLASS_S. java.lang.StringBuffer is a special case. It results in a dynamic string descriptor with a type of DSC$K_CLASS_D. Prior to a call the content of the StringBuffer object is copied into a dynamic descriptor. Then following the return from the call the string descriptor is copied back into the StringBuffer object so the result it can be used in the Java environment.
All objects and arrays passed by descriptor can be used to receive results, with one exception. The vs.ByDesc constructor for the java.lang.String object cannot be used to receive a result. This is a restriction imposed by Java, not J2VMS. There is no public method for updating the contents of a String object. In the case where a string object is passed by descriptor it results in a new byte array being allocated and the contents of the String object being copied into it. The example below demonstrates what actually happens.
Example 2-1 shows a literal java.lang.String object being passed to the LIB$ Run-Time Library routine LIB$PUT_OUTPUT. This example demonstrates the convenience of being able to pass string literals and have them built "in the argument list".
Example 2-1 Passing a java.lang.String Object by Descriptor |
---|
lib.lib$put_output(new VMSparam[] { new ByDesc("hello, " + "world") }); |
However, it is not possible to receive data into a String object. Example 2-2 is a complete program that can be copied and executed to demonstrate the restriction. This example is also available from the Kednos website, or online at SYS$COMMON:[SYSHLP.EXAMPLES.J2VMS]GET2.JAVA.
Example 2-2 Receiving String Data From A Called Routine |
---|
import java.lang.*; import vs.*; public class get2 { public static void main(String[] args) { Short result_len = new Short((short) 0); String result1 = new String(); StringBuffer result2 = new StringBuffer(); LibRoutines lib = new LibRoutines(); System.out.println("Storage before any calls to LIB$PUT_OUTPUT"); System.out.println(" * result_len = " + result_len); System.out.println(" * result1 = <" + result1 + ">"); System.out.println(" * result2 = <" + result2 + ">"); lib.lib$get_input(new VMSparam[] { new ByDesc(result1), new ByDesc("String result>> "), new ByRef(result_len) }); System.out.println("Storage after first call to LIB$PUT_OUTPUT"); System.out.println(" * result_len = " + result_len); System.out.println(" * result1 = <" + result1 + ">"); System.out.println(" * result2 = <" + result2 + ">"); lib.lib$get_input(new VMSparam[] { new ByDesc(result2), new ByDesc("String result>> "), new ByRef(result_len) }); System.out.println("Storage after second call to LIB$PUT_OUTPUT"); System.out.println(" * result_len = " + result_len); System.out.println(" * result1 = <" + result1 + ">"); System.out.println(" * result2 = <" + result2 + ">"); } } |
Table 2-1 summarises the native usage of Java object types passed by descriptor.
Java Class/Primitive Type | Descriptor Class | Writable |
---|---|---|
byte[] | Static (DSC$K_CLASS_S) | Yes |
int[] | Static (DSC$K_CLASS_S) | Yes |
long[] | Static (DSC$K_CLASS_S) | Yes |
short[] | Static (DSC$K_CLASS_S) | Yes |
java.lang.Byte | Static (DSC$K_CLASS_S) | Yes |
java.lang.Integer | Static (DSC$K_CLASS_S) | Yes |
java.lang.Long | Static (DSC$K_CLASS_S) | Yes |
java.lang.Short | Static (DSC$K_CLASS_S) | Yes |
java.lang.String | Static (DSC$K_CLASS_S) | No |
java.lang.StringBuffer | Dynamic (DSC$K_CLASS_D) | Yes |
vs.Cmem | Static (DSC$K_CLASS_S) | Yes |
vs.VmsStruct | Static (DSC$K_CLASS_S) | Yes |
There is currently no support for passing arrays by descriptor in the same way as other native high level languages. Currently all arrays of primitive types are treated as byte[] arrays. However, support is planned in a future release. |
Next | Contents |