HP.com home

User Guide

Software Development Kit (SDK) v 1.4.x
for the OpenVMS Operating System

for the Java™ Platform


Content starts here Content starts here

Contents

Back to top
Introduction

This User Guide contains information on using the Software Development Kit (SDK) v 1.4.x for the OpenVMS Operating System for the Java™ Platform (hereafter called simply the SDK), as well as information on using the HotSpot VM, using the Fast VM, using the Plug-in, troubleshooting, and documentation. This document references SDK v 1.4.x, where x is the specific version number of the release you are using. To check the version of your SDK, use the java -version command or refer to the Release Notes. The SDK can be used to develop and run Java applets and programs on OpenVMS systems.

Note: Sections with the alpha only designation apply only to Alpha systems running the OpenVMS Operating System and not to the I64 platform. Likewise, sections with the itanium only designation apply only to Integrity (I64) systems running the OpenVMS Operating System and not to the Alpha platform.

For information on the specific version of the SDK, such as installation instructions, new features, known issues, and fixed problems, refer to the Release Notes. The Release Notes also contain information on the following:

  • The J2SDK from Sun that the SDK implements
  • The specific Solaris Reference Release on which the SDK is based
  • Sun's Java Compatibility Kit test suite, whose tests the SDK passes
  • Prerequisites, including supported operating system versions

The SDK contains the following virtual machines:

  • itanium only The HotSpot Virtual Machine is based on Sun's reference implementation. The HotSpot VM contains Just-In-Time (JIT) compiler technology, designed to maximize performance. To learn more about the HotSpot VM, refer to Using the HotSpot VM. The HotSpot VM runs only on OpenVMS I64 systems and not on the Alpha platform.
  • alpha only The Fast Virtual Machine is Just-In-Time (JIT) compiler technology designed to provide optimal Java runtime performance on OpenVMS Alpha systems. The Fast VM offers significant performance advantages over the classic virtual machine. Because the Fast VM is included in the SDK, it is not provided as a separate kit. To learn more about the Fast VM, refer to Using the Fast VM. The Fast VM runs only on OpenVMS Alpha systems and not on the I64 platform. The SDK for Alpha also contains the classic JIT that is based on Sun's reference implementation and provides additional debugging support not currently available in the Fast VM. You select which virtual machine to use when you set up your Java environment. To set up your environment, see Alpha Implementation.

Getting Started

The Java programming language on OpenVMS, in its final version, is a fully compliant implementation and successfully passes Sun's Java Compatibility Kit (JCK) qualification suite. Any pure Java application that does not rely on the specific characteristics of another platform will, with minor effort, operate on OpenVMS.

Note: You need to know some significant differences in developing Java applications on OpenVMS systems. Read the following sections, along with the Interpreting Commands and OpenVMS Operating System Differences section and the Functionalities that Differ on OpenVMS section, for critical usage information that will save you time and effort. Also, refer to Optimizing Java Technology Software Performance on OpenVMS for tips on improving performance on OpenVMS systems.

The following sections discuss setting up and using the SDK.

Setting Process Quotas for Better Performance on OpenVMS

The Java runtime environment was designed to perform optimally on UNIX systems, where each process is given large quotas by default. On OpenVMS, the default behavior gives each process lower quotas so that many processes can co-exist on a system.  To get the best Java performance on OpenVMS, HP recommends that you set process quotas to match a typical UNIX system. HP also recommends these as minimum quota settings (except where noted).

The following numbers closely match the default UNIX process quota settings:

UAF Fillm

4096

Channelcnt

4096

Wsdef

2048

Wsquo

4096

Wsextent and Wsmax

16384

Pgflquo

2097152*

bytlm

400000

biolm

150

diolm

150

tqelm

100

*A good number for Pgflquo is (2 x heap-size), for example, 128 MB (2*128*1024*1024)/512 = 524288. Recall that the recommended minimum Pgflquo is 96 MB (when using the RTE on Alpha). When you increase the Pgflquo parameter, you should always increase the system's page file size to accommodate the new Pgflquo parameter, if needed. The minimum required value for Pgflquo for use with the RTE on I64 is 250 MB.

Setting Up the Java Environment

On OpenVMS, you run a version-specific command procedure to set up the Java environment:

SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP.COM

where x is the specific version number of the release you are using.

Note: For simplicity, this document assumes you installed the SDK using the default location and therefore references SYS$COMMON:[JAVA$14x] throughout the text. However, if you specified a destination and installed the kit in that alternate location, substitute that location for the default while reading this document. Also in all these references, 'x' is the specific version number of the release you are using.

JAVA$14x_SETUP.COM does the following:

  1. Sets up symbols to allow using Java commands (for example, java, javac, and jar) as foreign commands

  2. Defines logical names for the SDK's shareable images

  3. Defines logical names for the virtual machine, based on your specification
    or the default

    There are differences between the virtual machines on different platforms. Fore more information, and specific details on invoking JAVA$14x_SETUP.COM, see I64 Implementation or Alpha Implementation.

  4. Sets up a default value for the logical name JAVA$FILENAME_CONTROLS. For more information, see UNIX-Style Filenames on OpenVMS Systems.

  5. Defines logical names needed to run Plugins with Mozilla

  6. Defines logical names that could be useful when writing local command
    procedures. In particular:

    JAVA$CANCEL_CURRENT - useful when switching from one version of the SDK to another, within the same process.

    JAVA$JRE_HOME_VMS - the VMS-style directory for the root of installed Java code (the area above the [.bin] directory). Its value is typically: SYS$COMMON:[JAVA$14x.jre].

    JAVA$JRE_HOME_UNIX - the Unix-style directory for the root of installed Java code (the area above the [.bin] directory). Its value is typically: /SYS$COMMON/JAVA$14x/jre.

    JAVA$JRE_HOME_UNIX and JAVA$JRE_HOME_VMS - location-independent names that are useful when
    writing local command procedures because the Java product need not be installed in the default location, SYS$COMMON.

The following two command procedures may assist you in your initial set-up of minimal quotas for using the Java programming language on OpenVMS. The files help you determine whether you are set up to run the Java programming language (quota-wise) and to generate a configuration file of $ DEFINE commands that you could invoke after running JAVA$14x_SETUP.COM. These command procedures are independent of JAVA$14x_SETUP.COM.

The first command procedure can be found in:

SYS$COMMON:[JAVA$14x.COM]JAVA$CONFIG_WIZARD.COM

When you execute the following procedure:

$ @SYS$COMMON:[JAVA$14x.COM]JAVA$CONFIG_WIZARD.COM

you are asked several questions about your environment and the Java application you intend to run.

Based on your answers, it generates a command procedure file (called JAVA$CONFIG_SETUP.COM) which, when executed, sets up the logical names that are appropriate for your intended usage.

The second command procedure can be found in:

SYS$COMMON:[JAVA$14x.COM]JAVA$CHECK_ENVIRONMENT.COM

When you execute the following procedure:

$ @SYS$COMMON:[JAVA$14x.COM]JAVA$CHECK_ENVIRONMENT.COM

it tests the process quotas in the current process and warns you if some of your account and sysgen quotas are not up to recommended level for running Java programs.

The following example illustrates a typical pattern for using these command procedures:

  1. One time-Am I set up quota-wise to run Java?

    $ @SYS$COMMON:[JAVA$14x.COM]JAVA$CHECK_ENVIRONMENT.COM

  2. One time-Build me a JAVA$CONFIG_SETUP.COM for my intended usage

    $ @SYS$COMMON:[JAVA$14x.COM]JAVA$CONFIG_WIZARD.COM

  3. Set up the Java environment, select VM

    $ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP.COM {FAST}

  4. Define my tailored set of logical names

$ @JAVA$CONFIG_SETUP.COM

Note: If you choose to run JAVA$CONFIG_SETUP.COM, be sure to run it after running JAVA$14x_SETUP.COM.

Switching Versions

You can have multiple SDK versions installed on your OpenVMS system, and you can change from one to the other. The following sections describe how to do this.

Note: For simplicity, this document assumes you installed the SDK using the default location and therefore references SYS$COMMON:[JAVA$14x] throughout the text. However, if you specified a destination and installed the kit in that alternate location, substitute that location for the default while reading this document.

In Separate Processes

To use different SDK versions in separate processes, you must first run a command procedure to set up the Java environment definitions for the version of the SDK you want to use in the given process. The command procedures to perform the Java environment setup are version-specific, and are as follows:

SDK Version

Command Procedure

SDK v 1.4.2 SYS$COMMON:[JAVA$142.COM]JAVA$142_SETUP.COM

SDK v 1.4.1

SYS$COMMON:[JAVA$141.COM]JAVA$141_SETUP.COM

SDK v 1.4.0 SYS$COMMON:[JAVA$140.COM]JAVA$140_SETUP.COM

SDK v 1.3.1

SYS$COMMON:[JAVA$131.COM]JAVA$131_SETUP.COM

SDK v 1.2.2

SYS$COMMON:[JAVA$122.COM]JAVA$122_SETUP.COM

SDK v 1.1.8

SYS$MANAGER:JAVA$SETUP.COM

For example, to run SDK v 1.4.2, first run the following command file in your process:

$ @SYS$COMMON:[JAVA$142.COM]JAVA$142_SETUP.COM

alpha only You can select either the Fast VM or the classic VM as your virtual machine using this command file. Refer to Alpha Implementation to set up the Java environment.

Note: To run the Fast VM with SDK v 1.3.0 or SDK v 1.2.2, you must install the appropriate version of Fast VM separately; it is not included on these SDK kits. The Fast VM is not available for SDK v 1.1.8. Refer to our Software download page for product listing.

In the Same Process

To use different SDK versions in the same process, you must first run a command procedure to cancel the Java environment definitions of one version of the SDK before setting up the environment of another version of the SDK. The command procedures to accomplish the Java environment cleanup are version-specific, and are as follows:

SDK Version

Command Procedure

SDK v 1.4.2 SYS$COMMON:[JAVA$14x.COM]JAVA$142_CANCEL_SETUP.COM or JAVA$CANCEL_CURRENT

SDK v 1.4.1

SYS$COMMON:[JAVA$14x.COM]JAVA$141_CANCEL_SETUP.COM

SDK v 1.4.0 SYS$COMMON:[JAVA$14x.COM]JAVA$140_CANCEL_SETUP.COM

SDK v 1.3.1

SYS$COMMON:[JAVA$14x.COM]JAVA$131_CANCEL_SETUP.COM

SDK v 1.3.0

SYS$COMMON:[JAVA$14x.COM]JAVA$130_CANCEL_SETUP.COM

SDK v 1.2.2

SYS$COMMON:[JAVA$14x.COM]JAVA$122_CANCEL_SETUP.COM

SDK v 1.1.8

SYS$COMMON:[JAVA$14x.COM]JAVA$118_CANCEL_SETUP.COM

where x is the specific version number of the release you are using. Note that older releases do not contain cancel procedures for later releases; for example, SYS$COMMON:[JAVA$141.COM] does not contain JAVA$142_CANCEL_SETUP.COM.

Once you have cancelled the Java environment, you must then run a command procedure to set up the Java environment definitions for the version of the SDK you want to use. For a list of these command procedures, see In Separate Processes.

For example, to switch from using SDK v 1.3.1 to using SDK v 1.4.2 in the same process, run the following command procedures:

@SYS$COMMON:[JAVA$142.COM]JAVA$131_CANCEL_SETUP.COM !Clean up 1.3.1 environment
@SYS$COMMON:[JAVA$142.COM]JAVA$142_SETUP.COM !Set up 1.4.2 environment

Running @SYS$COMMON:[JAVA$142.COM]JAVA$131_CANCEL_SETUP.COM cancels the setup of the SDK v 1.3.1 environment.

Starting with SDK v 1.4.2, the JAVA$CANCEL_CURRENT logical name provides the full file specification of the command procedure used for canceling the setup for the most recent version of Java set up.

For example, the value of JAVA$CANCEL_CURRENT will be SYS$COMMON:[JAVA$142.COM]JAVA$142_CANCEL_SETUP.COM if your most recent setup command was:

$ @SYS$COMMON:[JAVA$142.COM]JAVA$142_SETUP.COM

JAVA$CANCEL_CURRENT allows you to freely type the command, $ @JAVA$CANCEL_CURRENT to undefine current Java logical names and symbols without knowing what the currently-enabled version is.

Back to top
Interpreting Commands and OpenVMS Operating System Differences

Though Sun's Tools and Utilities documentation specifies all the details about operating various tools, you must interpret the literal examples of commands with an eye to OpenVMS differences. The following table attempts to describe how the OpenVMS Operating System differs from the UNIX environment in which the Java platform originated.

Note: You must understand these differences to operate these tools successfully on OpenVMS.

OpenVMS Usage

Explanation

Stream_LF

All files read by Java code (.java, .class, .jar, etc.) must have a Stream_LF record format. To learn how to check whether files are Stream_LF and how to convert them if they are not, see Stream_LF File Format Required. Files created by Java tools will automatically be Stream_LF.

Role of JAVA$CLASSPATH

A number of tools rely on either a -classpath argument on the command line, or rely on the setting of a logical CLASSPATH--a colon-separated search list of directories in UNIX-style filename syntax. Sometimes it is easier to fabricate a comma-separated search list of directories in OpenVMS-style file syntax. This is done with a logical named JAVA$CLASSPATH. See Setting JAVA$CLASSPATH for details on JAVA$CLASSPATH and its interaction with CLASSPATH and -classpath.

Quoting Operand

Certain operands need to be quoted; Java tools are case-sensitive throughout their operation. Command-line operands are automatically lower-cased as they are acquired from the command line. In order to preserve the case so that these operands are acceptable to Java commands, you must quote them. The most common instances of this are:

  • Need to quote upper-case switches
    Memory allocation on Java command.
    $ java "-Xmx64m" mytest

  • Need to quote class names and package names
    Class name specification
    $ java "MyPackage/MyTest"

  • Need to quote upper-case keywords
    Encoding type keyword
    $ native2ascii -encoding "ISO8859_1" data.txt
    data.txt

See One-to-One Relationship Between Class Names and File Names for further discussion and examples of where quoting is needed.

Combating limitations on DCL command-line length

DCL command-line length is limited. While the limit has increased in later OS versions, constructing longer command lines is frequently convenient (and sometimes necessary).

For example, you cannot build command lines like the following, if they exceed the character limit:

$ javac "MyClass001.java" -
"MyClass002.java" -
"MyClass003.java" -
...
"MyClass127.java" -
"MyClass128.java"

To work around this limitation on the OpenVMS Operating System, the RTE has been customized to allow you to place operands into a data file and then simply point to the data file on the command line. The @files feature of the SDK allows you to put command operands in another file and simply name that operand file prefixed with an @ sign.

For example, you can write the following:

$ javac @CLASS_LIST_FILE.DAT

where CLASS_LIST_FILE.DAT contains:

MyClass001.java
MyClass002.java
MyClass003.java
...
MyClass127.java
MyClass128.java

Another usage is:

$ javac @sys$input:
MyClass001.java
MyClass002.java
MyClass003.java
...
MyClass127.java
MyClass128.java

Note that operands on the command line need to be in quotation marks to keep DCL from uppercasing the arguments, but the same arguments in a file do not need to be in quotes because they are not directly interpreted by DCL. File names appearing in the input file specified by @ should be in UNIX format rather than OpenVMS format and should not be in quotation marks.

Also, on OpenVMS, you can use "-V" in place of @files to achieve the same behavior. For example, you can type:

$ javac "-V" FILES_TO_COMPILE.DAT

where FILES_TO_COMPILE.DAT contains (the potentially long) list of files to compile. Note that the -V is quoted for reason cited above. (See also Using White Space Within "-V" Data Files.)

You can use "-V" with other Java commands in addition to javac; for example, you can write the following:

$ java "-V" name_of_file_containing_operands.dat

Note: The existence or accessibility of the file specified by -V is not tested. If the file does not exist or cannot be opened, then no additional data is added to the command line being built; no error is reported.

Using White Space Within "-V" Data Files

If, within the data file used as input to "-V" processing, an operand has white space, it will not be parsed correctly.

For example, the quoted argument on the following command line

$ java xargs "< = 1" 2 3

will work. The arguments will be interpreted as:

< = 1
2
3

If you put the parameters into a data file called datafile1.txt, e.g.,

< = 1
2
3

and then access them via:

$ java xargs "-V" datafile1.txt

they will be interpreted as:

<
=
1
2
3

The white space breaks up the processing of the line.

Even if you enclose the operand in quotes, as in a data file called datafile2.txt,

"< = 1"
2
3

and then access them via:

$ java xargs "-V" datafile2.txt

they will be interpreted as:

"<
=
1"
2
3

The white space still breaks up the processing of the line. Note that the quotation marks are retained.

The JAVA$DISABLE_CMDFILE_WHITESPACE_PARSING logical name enables you to provide operands that contain white space within the data file.

$ define/job JAVA$DISABLE_CMDFILE_WHITESPACE_PARSING TRUE

When this logical is defined, spaces and tabs are no longer treated as delimiters in "-V" files. Each line in the file is treated as a single command-line argument.

Note: If the line contains a space, this space will be included as part of the command argument.

For example, in:

$ create java_input.dat
param1 param2
^Z

$ java "-V" java_input.dat

Without the logical JAVA$DISABLE_CMDFILE_WHITESPACE_PARSING defined, the RTE sees two command line arguments: param1 and param2.

With the logical JAVA$DISABLE_CMDFILE_WHITESPACE_PARSING defined, the RTE sees only one command-line argument, param1 param2.

You can use the _JAVA_LAUNCHER_DEBUG logical name as a diagnostic tool, to see the arguments as they are passed to the Java Virtual Machine.

Alternatively, you can provide these parameters on the command line itself.

Dealing with UNIX-style filenames that cannot be represented on OpenVMS

The OpenVMS file system on ODS-2 formatted disks cannot represent certain legitimate UNIX-style file names; for example, a file named font.properties.ja cannot be created.

On OpenVMS, the RTE supports a filename remapping strategy that allows you to represent otherwise-unrepresentable filenames via a filename-mapping capability. This allows you to specify, for example, that all filenames presented with multiple dots in their names should be stored and retrieved as if all of the dots, except the last, have been replaced by underscores; hence the file above would be methodically read and written as if it were named font_properties.ja.

To learn more about other possible filename mappings, see UNIX Style Filenames on OpenVMS Systems.

Specifying multiple paths using the UNIX file path syntax

The parsing of the values for the switches -classpath, -bootclasspath, and -sourcepath disallows the mixing of UNIX file path syntax and OpenVMS file path syntax.

If a path specified by one of these switches contains mixed OpenVMS and UNIX-style path syntax, an error will be displayed.

Getting around limitation of directory depth of 8 on ODS-2 disks

The OpenVMS file structure on ODS-2 formatted disks limits you to only eight levels of directories. It is not uncommon for Java programs imported from elsewhere to have a package structure that is more than eight levels deep.

To circumvent these limitations on OpenVMS, the RTE supports a filename remapping strategy that allows you to represent the deeper structure in a more shallow directory. Refer to Description of Mapping Options to see how this is accomplished.

Approximating Functionality That Does Not Exist: dlopen, dlsym, and dlclose

OpenVMS systems do not have a dlopen, dlsym, and/or dlclose runtime routine. To be able to support dynamically loaded runtime libraries, we have created dlopen, dlsym, and dlclose routines using LIB$FIND_IMAGE_SYMBOL (FIS).

FIS does not support pure dynamically linked library in the same manner as dlopen does. FIS does NOT resolve global symbols from other shareable libraries at runtime. Under OpenVMS, this must be done at link time, and not at runtime.

Example:

The Java Zip library needs java_lang_String_intern, which is declared in the main Java library (JAVA.SO). On UNIX systems, dlopen resolves this external global at runtime.

On OpenVMS systems, because FIS does NOT resolve any external globals at runtime that were not found at link time, the Java Zip library must be linked against the main Java library to allow java_lang_String_intern to be found at runtime.

 

Back to top
Functionalities That Differ on OpenVMS

The following functionalities either work differently on other platforms than they do on OpenVMS, or OpenVMS does not support them.

Virtual Machine Is Set Up in Advance

On OpenVMS, you set up the virtual machine in advance. There are differences between the virtual machines on different platforms. For more information, see I64 Implementation and Alpha Implementation.

Javald Not Ported to SDK v 1.4.x for OpenVMS

Javald has not been ported to the SDK v 1.4.x for OpenVMS.

Java Sound Not Supported

Java Sound is not supported. The following error is reported if you attempt to use Java Sound:

Java Sound support not currently available

RTE Does Not Support Using ^\ to Print Out Java Stack

On OpenVMS systems, the RTE does not support the use of typing ^\ to get a printout of the Java stack. For more information, refer to JAVA$ENABLE_SIGQUIT_CTRLC and JAVA$ENABLE_SIGQUIT_MAILBOX.

C RTL Default Behavior with seek() Behavior

When seeking beyond the end of a file, the default behavior of the C RTL is to physically extend the file. Depending on the offset specified in the seek operation, this can take a long time. This behavior differs from most UNIX systems, where the file is only extended if you write to it after the seek operation.

To enable the UNIX behavior on OpenVMS systems, uncomment the definition of the DECC$POSIX_SEEK_STREAM_FILE logical in the JAVA$14x_SETUP.COM file, where x is the specific version number of the release you are using.

Multiple Listeners Can Bind to the Same Socket: A Nonportable TCP/IP Behavior

On OpenVMS systems, TCP/IP allows multiple listeners to bind to the same socket. This behavior is different from that exhibited on some other operating systems, where this phenomenon is detected and the following exception is thrown:

"java.net.BindException: Address already in use"

This is not a behavior specific to the RTE, but the way that TCP/IP Services works on OpenVMS systems. This difference is noted to caution you from relying on this exception if you intend to write portable Java applications.

Javadoc Fails to Distinguish Class and Package Names in the Same Directory

Javadoc fails to distinguish class and package names that reside in the same directory and differ only in case. An example is the package java.awt.event and the class java.awt.Event.

Back to top
Stream_LF File Format Required

All Java files that are to be read by any of the Java tools or that serve as input class libraries (listed in CLASSPATH) must be in Stream_LF format. Stream_LF format is required for all data files read or written by Java programs.

To determine the record format of your file, do the following:

$ DIR/FULL MyFile.java

And observe the line:

Record format:

By default, a file initially created on an OpenVMS system, with a text editor for example, will have 'Variable length' record format.

Although a *.java file with 'Variable length' record format compiles correctly if it is error-free, the compiler does not produce proper diagnostic outputs if a compilation error occurs.

Forcing Stream_LF File Format

On OpenVMS, when you create a new version of an existing file, the new file will inherit the record format of the existing file. The record format preferred/required by the RTE is Stream_LF. The RTE allows you to specify a logical:

$ DEFINE JAVA$CREATE_STMLF_FORMAT TRUE

With this logical defined, the RTE will force any newly-created file to have a Stream_LF format. This allows the RTE to override the C Run-Time Library's default of inheriting existing file format from previous versions, which might not behave correctly with the RTE.

Converting ASCII Files

To get an ASCII file into Stream_LF record format, do the following:

$ CONVERT/FDL=SYS$COMMON:[JAVA$14x.COM]STREAM_LF.FDL input_filename -
output_filename

where x is the specific version number of the release you are using, and where STREAM_LF.FDL is:

    FILE
            ALLOCATION              4
            BEST_TRY_CONTIGUOUS     yes
            EXTENSION               0
            ORGANIZATION            sequential

    RECORD
            BLOCK_SPAN              yes
            FORMAT                  stream_LF
            SIZE                    0

If the file is in the proper format (Stream_LF), you will see the source error line printed out, with a carat (^) indicating the point of error:

$ javac "Bounce.java"
Bounce.java:11: Superclass smith.java.applet.Applet of class Bounce not found.
public class Bounce extends smith.java.applet.Applet implements Runnable
                            ^
1 error

If the file is not in Stream_LF format, a blank line is printed instead of the source error line, and the carat position is not useful:

$ javac "Bounce.java"
Bounce.java:10: Superclass smith.java.applet.Applet of class Bounce not found.
                                                                    ^
1 error

Converting Binary Files

Binary .class files need to be Stream_LF as well. If they are not Stream_LF you will get error messages like the following, even though your CLASSPATH is correct and the correct .class file is on the path:

Can't find class Test.HelloWorld

If you import .class files from a non-OpenVMS system, be sure to convert them to Stream_LF.

To get a binary file (.class, .jar, .zip) into Stream_LF record format, do the following to give the file the right record format attributes:

$ SET FILE/ATTR=(RFM:STMLF,RAT:CR) filespec

Debugging Tips For File Format Problems

  1. Are the files Stream_LF Record Format?

  2. Turn on JAVA$SHOW_FILENAME_MAPPING for a trace of filename translation.

Back to top
UNIX-Style Filenames on OpenVMS Systems

There are a number of issues trying to represent UNIX directory and file specifications on an OpenVMS system. If you try to run a Java application developed elsewhere on an OpenVMS system, you might encounter problems with file and directory names.

The RTE provides a number of mapping algorithms that try to make a UNIX-style name usable under an OpenVMS file system.

These algorithms can be used in combinations. You can enable the use of each algorithm by turning on a particular bit in the following logical name:

JAVA$FILENAME_CONTROLS

To change the JAVA$FILENAME_CONTROLS default values, edit the file: SYS$COMMON:[JAVA$14x.COM]JAVA$FILENAME_CONTROLS.COM

where x is the specific version number of the release you are using.

This file is called by JAVA$14x_SETUP.COM to establish these and other defaults.

We suggest that you start off using this file as-is to enable all algorithms.

Different users may want to read/edit this file to enable/disable different algorithms to avoid selected problems.

The algorithms and the bit values to set them are summarized below. A more detailed explanation of each option follows the table.

Current Filename Mapping

Option Name

Value

Support UNIX and OpenVMS filename

%x00000008

Support dir in the filename

%x00000200

Support valid characters in filename

%x00001000

Support hidden filename (replace with _)

%x00004000

Support hidden filename (remove the .)

%x00008000

Support multi dot in directory (replace with _)

%x00020000

Support multi dot in directory (remove dots)

%x00040000

Support multi dot in file, keeping last

%x00100000

Support multi dot in file, keeping first

%x00200000

Support more than 39 characters by truncation

%x04000000

Support more than 39 characters by moving the dot

%x08000000

Support directory remapping

%x20000000

To see individual filename mappings as they occur, define the logical JAVA$SHOW_FILENAME_MAPPING:

$ DEFINE JAVA$SHOW_FILENAME_MAPPING 1

This is useful if you are experiencing problems with the way filenames are being mapped, perhaps resulting in unexpected "File not found" messages.

Example:

To enable "UNIX and VMS" and "Multi dot first" you must issue the following DEFINE:

$ FILE_MASK = %x00000008 + %x00200000
$ DEFINE JAVA$FILENAME_CONTROLS 'file_mask'

The options are processed at runtime in order from smallest to largest values.

Therefore, in this example, first "UNIX and VMS" would be processed, and then "Multi dot first".

To enable all the options:

$ DEFINE JAVA$FILENAME_CONTROLS -1

If JAVA$FILENAME_CONTROLS is not defined or is equal to zero, then no mappings are attempted.

Description of Mapping Options

The following sections further describe the available mapping options.

Support UNIX and OpenVMS Filename

Use this to map a mix of UNIX and OpenVMS filenames into UNIX-style names.

For example, a name like:

$disk1:[smith]/test.jtjtj/test.jtjtj

maps into:
/$disk1/smith/test.jtjtj/test.jtjtj

Support dir in the Filename

Change names of the form xxx.dir to their UNIX directory counterpart.

For example, a name like:

/dkb500/smith.dir/testing.dat

maps into:
/dkb500/smith/testing.dat

Support Valid Characters in Filename

Characters that can occur in UNIX-style names but are prohibited in OpenVMS-style names are replaced by underscores (_), unless these characters have special meaning in the UNIX-style name. In that case, we attempt to map the special meaning.

For example, "~" refers to SYS$LOGIN.

The list of characters contains characters like "+".

No uppercasing is done. C will create/open the correct file.

Support Hidden Filename (Replace with _)

Some Java applications expect to be able to create a hidden file or directory. The hidden character "." will be replaced by the "_" character.

For example, a name like:

.hotjava

maps into:

_hotjava

Or, a name like:

test/.hotjava/appletviewer.dat

maps into:

test/_hotjava/appletviewer.dat

Support Hidden Filename (Remove the .)

Some Java applications expect to be able to create a hidden file or directory. The hidden character "." will be removed from the filename.

For example, a name like:

.hotjava

maps into:

hotjava

Or, a name like:

test/.hotjava/appletviewer.dat

maps into:

test/hotjava/appletviewer.dat

Support Multi-dot in Directory, Replacing All by Underscore

Multiple dots in directories are replaced with underscores.

For example, a name like:

/dkb500/smith/version1.1.4.3/testing_dat.dat

maps into:

/dkb500/smith/version1_1_4_3/testing_dat.dat

Support Multi-dot in Directory, Removing All Dots

Multiple dots in directories are removed.

For example, a name like:

/dkb500/smith/version1.1.4.3/testing_dat.dat

maps into:

/dkb500/smith/version1143/testing_dat.dat

Support Multi-dot in File, Keeping the Last Dot

Multiple dots in the filename are turned into underscores, but the last dot is retained.

For example, a name like:

SDKDOC_1.4.0

maps into:

SDKDOC_1_4.0

Support Multi-dot in File, Keeping the First Dot

Multiple dots in the filename are turned into underscores, but the first dot is retained.

For example, a name like:

SDKDOC_1.4.0

maps into:

SDKDOC_1.4_0

Support Greater than 39-Character Filenames by Truncation

For filenames greater than 39 characters either to the left or the right of the single dot, that portion of the name is truncated on the right.

For example, a name like:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.extension

maps into:

abcdefghijklmnopqrstuvwxyzabcdefghijklm.extension

Similarly, a name like:

somename.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

maps into:

somename.abcdefghijklmnopqrstuvwxyzabcdefghijklm

Support Greater than 39-Character Filenames by Moving the Dot

For filenames that have more than 39 characters either to the left or to the right of the single dot in the filename, AND the total number of characters is less than [39+39 =] 78, the algorithm tries to shift the single dot so that there are no more than 39 characters to the left of the dot.

For example, a name like:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.extension

maps into:

abcdefghijklmnopqrstuvwxyzabcdefghijklm.nopqrstuvwxyzextension

Support Directory Remapping

There is support for representing a directory structure that is more than eight levels deep on an ODS-2 format disk.

If your application will use more than the OpenVMS maximum of eight nested directories, then define the following logicals to work around this restriction:

JAVA$DIRECTORY_MAPPING_COUNT nn : How many directory mappings exist?

JAVA$DIRECTORY_MAPPING_nn : Directory mapping value

where nn is an integer from 01 to 99.

For example, the following filename previously failed with SDK v 1.1.n for OpenVMS because the directory has too many levels for RMS:

/test1/test2/test3/test4/test5/test6/test7/test8/test9/test10

Using the directory mapping logic, you can redirect deep directory names to either a concealed logical or another directory.

Using the example above:

$ DEF JAVA$DIRECTORY_MAPPING_COUNT 1 ! how many directory mappings.

$ DEF JAVA$DIRECTORY_MAPPING_01 -
_$ "/test1/test2/test3/test4/test5/test6/test7=/test7_relevel"

All files/directories created with a prefix of the following will now be created in the directory /test7_relevel:

/test1/test2/test3/test4/test5/test6/test7

So, the filename:

/test1/test2/test3/test4/test5/test6/test7/test8/test9/test10/foo.bar

would actually be created as:

/test7_relevel/test8/test9/test10/foo.bar

Note: Define the JAVA$DIRECTORY_MAPPING_nn logical only from the first character on. You cannot map directories from the middle of a directory tree. Note the limit of 99 remappings.

Improving Memory Utilization by Reducing Filename Mapping

Historically, at users' request, the RTE has performed filename mapping to map file names that are not directly representable on an OpenVMS file system into ones that are representable. This filename mapping requires several (potentially large) buffers on the stack. As the number of requested mappings increases, an increasingly larger number of such buffers are required. See Description of Mapping Options in UNIX-Style Filenames on OpenVMS Systems for a full discussion of these filename mappings.

The C RTL contains functionality that enriches the kinds of filenames you can directly specify on an ODS-5 volume under OpenVMS. If the files for your application are restricted to an ODS-5 volume, then you can probably reduce the number of filename mappings that you request.

Whenever you eliminate a filename mapping option, you reduce the number of internal buffers that need to be allocated—leading to a smaller memory footprint for your application. When no filename mapping is needed (JAVA$FILENAME_CONTROLS defined to 0 or is undefined), you can lower the -ss (stack size) value. The gains will be in memory usage and thread creation.

Back to top
Setting JAVA$CLASSPATH

The JAVA$CLASSPATH logical is an alternative way of specifying the class path. Defining this logical overrides the CLASSPATH logical, if set.

JAVA$CLASSPATH lets you define a class path using OpenVMS file specification syntax. Therein lies its advantage: with JAVA$CLASSPATH, you specify multiple paths with a comma-separated expression; with CLASSPATH, you use a single, quoted string comprised of colon-separated pathnames. JAVA$CLASSPATH, therefore, avoids the OpenVMS 255-character length restriction that you can encounter with CLASSPATH.

The following two sample statements accomplish the same result:

$ DEF JAVA$CLASSPATH USER1$:[SMITH.KIT]MY_CLASSES.ZIP,[]

$ DEF CLASSPATH "/user1$/smith/kit/my_classes.zip:."

Note that:

  • CLASSPATH is a colon-separated list enclosed in quotes.
  • JAVA$CLASSPATH is a comma-separated list not enclosed in quotes.
  • JAVA$CLASSPATH overrides CLASSPATH, if JAVA$CLASSPATH is defined.
  • The -classpath option on a Java tool overrides both JAVA$CLASSPATH and CLASSPATH.

For further information, see Setting the Classpath on Sun's site.

Using JAVA$ENABLE_ENVIRONMENT_EXPANSION

You can use the JAVA$ENABLE_ENVIRONMENT_EXPANSION logical to bypass the DCL command-line character limit:

$ define/job JAVA$ENABLE_ENVIRONMENT_EXPANSION TRUE

When this logical is defined, the RTE will attempt to expand any logical or symbol that is preceded by "$" on the Java command line. To bypass the DCL command line character limit, you can define lengthy command-line operands as more compact symbols or logical names and specify them on the Java command line, each preceded by a "$". They will be passed by DCL to the RTE for expansion. Also, if the logical is a multi-valued logical, this feature will attempt to convert the list into a UNIX list with a ":" as a delimiter.

For example:

$ define java$classpath [], dka200:[apache.jakarta.tomcat.lib]servlet.jar
$ extra_option = "-Dfoobar=value1 -Dfoobar1=value2"
$ java -cp $java$classpath $extra_option javaprogram

With the logical defined, the RTE would expand the command line to the following:

$ java -cp .:/dka200/apache/jakarta/tomcat/lib/servlet.jar -
" -Dfoobar=value1" "-Dfoobar1=value2" javaprogram

Note: This feature does not expand operands provided via the "-V" method.

You can use the _JAVA_LAUNCHER_DEBUG logical name as a diagnostic tool to see the arguments as they are passed to the Java Virtual Machine.

Back to top
Relaxation in Shareable Image Name Usage

There is a relaxation in the way shareable image names are used.

Before SDK v 1.1.8, the JNI example provided for OpenVMS systems suggests you put your native code into a shareable image named JAVA$foo_SHR.EXE, where you choose the foo portion of the image name. In your Java code, you would have the following statement to load your shareable image so you can call its native methods:

   System.loadLibrary("foo");


This has the disadvantage of requiring users to create shareable images using our reserved name prefix of JAVA$.

As of SDK v 1.1.8, you are allowed and encouraged to create shareable image names that do not collide with our namespace:

  • To avoid naming conflicts with future releases, do not prefix user application shareable images with JAVA$. You can avoid naming your images JAVA$foo_SHR as long as you define a logical name JAVA$foo_SHR to point to your image.

    As a workaround to support old SDKs, we recommend you define two logical names: "JAVA$foo_SHR" and "foo", both pointing to your foo.exe shareable image:

    $ DEFINE/JOB JAVA$foo_SHR USER_DISK:[FOO]FOO.EXE

    $ DEFINE/JOB foo USER_DISK:[FOO]FOO.EXE

    The corresponding statement in your Java code would be:

    System.loadLibrary("foo");

    When you no longer support SDKs prior to SDK v 1.1.8, you could stop defining the JAVA$foo_SHR logical. The foo logical would then continue to get you to your shareable image.

  • Consider using a project prefix for shareable image names.

  • Put the real library name in the call to loadLibrary. For example, if a user application has an image named FOO.EXE, then the call would be:
    System.loadLibrary("foo");
  • Do not put your shareable images (or .class files) in the SYS$COMMON:[JAVA...] area. Instead, use the CLASSPATH logical to make user classes known to the environment. Future releases of the SDK could contain additional images and/or .class files that might conflict with user file names. (This is another good reason for you to use a project prefix as suggested in the second item above.)

Back to top
Interfacing with non-Java Code

The SDK kit provides examples, in SYS$COMMON:[JAVA$14x.VMS_DEMO], that demonstrate step-by-step what is needed to write native C programs to interact with Java code. Each example is in the form of a set of files that contain sample Java and C code, which shows the basics of how they interact, as well as command procedures that will compile, link, and execute the sample JNI-based application. See the following sections for more information on calling C code from Java code, calling OpenVMS System Services from Java code, and invoking Java methods from C code.

Calling C Code from Java Code

The SDK kit provides file JNI_EXAMPLE.SAV that demonstrates how to call C code from Java code. It also demonstrates how to handle procedure names over 31 characters, also discussed in the Name-Shortening Capability section.

There are two ways to shorten external names that are longer than 31 characters.

  1. The RTE has the capability to shorten long procedure names (more than 31 characters) using the same translation algorithm used by the C/C++ compilers from HP. To make use of this feature, compile your C/C++ code with the /NAMES=(AS_IS,SHORTENED) qualifier. The SHORTENED keyword for this qualifier instructs the compilers to shorten external names that are longer than 31 characters. The RTE automatically shortens long names using the same algorithm. This method is recommended, as it simplifies the process of building native images, and can make debugging easier, too. The file JNI_EXAMPLE.COM, in the JNI_EXAMPLE.SAV save set, demonstrates this method.

  2. If you are using an older version of the SDK than listed above, or you don’t wish to use the SHORTENED keyword on the /NAMES qualifier, you can use the utility program contained in the JNI_EXAMPLE.SAV save set. This utility will manually shorten the long names in your native code. The file JNI_EXAMPLE_31CHARS.COM demonstrates this method.

To obtain and use the example:

  1. Restore the save set:

    $ BACKUP SYS$COMMON:[JAVA$14x.VMS_DEMO]JNI_EXAMPLE.SAV/SAVE [...]*.*

  2. Go to the example directory created by BACKUP:

    $ SET DEFAULT [.JNI]

  3. Read JNI_README.TXT for an overview of what files are in this package.

  4. Read/Execute JNI_EXAMPLE.COM or JNI_EXAMPLE_31CHARS.COM to see how it all works. Note: You will first need to update the procedure to reflect the version of the Java environment you are running.

Calling OpenVMS System Services from Java Code

The SDK kit provides file SYSTEM_SERVICE_INVOKE_DEMO.SAV that demonstrates how to call OpenVMS System Services from Java code. It is a complete example that compiles and links everything it needs from the components in the demo kit file.

It creates two classes—LibGetJPI and LibGetSYI—which act as jacket routines that call Java Native Interface (JNI) C-based native code that actually accesses the GETJPI and GETSYI system services.

This example demonstrates several techniques:

  • Defining the needed item codes, etc. at the Java level. This is accomplished by creating *DEF*.java files which were hand-edited from their corresponding *DEF*.h files for these system services.

  • The use of packages to organize the overall positioning of these files within a larger application.

  • The approach of creating classes to represent these system services—thereby allowing seamless Java-based access to the results of these system service calls.

  • The creation of shareable libraries to allow the dynamic loading of these services as needed.

  • The use of SCAN_GLOBALS_FOR_OPTION.COM and JAVA$BUILD_OPTION.EXE to dynamically create the .OPT files needed for linking the shareable libraries.

To obtain and use the example:

  1. Restore the save set:

    $ BACKUP -
    SYS$COMMON:[JAVA$14x.VMS_DEMO]SYSTEM_SERVICE_INVOKE_DEMO.SAV/SAVE [...]*.*

  2. Go to the example directory created by BACKUP:

    $ SET DEFAULT [.SYSTEM_SERVICE_INVOKE_DEMO]

  3. Set up your Java environment, e.g.,

    $ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP.COM

  4. Read/Execute the command procedure that builds the example from scratch and executes it. Note: You will first need to update the procedure to reflect the version of the Java environment you are running.

    $ @BUILD_EXAMPLE.COM

Invoking Java Methods from C Code

The SDK kit provides file INVOKE_JAVA_FROM_C_EXAMPLE.SAV that demonstrates how to write an application that starts in C code and then calls Java methods.

The example program demonstrates:

  • Compiling and linking the example.

  • Starting application in C code.

  • Activating a virtual machine.

  • Calling a Java method that, in turn, throws an exception. The sample code shows how to detect and process the Java exception.

  • Calling a Java method that, in turn, calls back to a native C routine—demonstrating how to establish callbacks in C code that are eventually called from the Java code.

  • The creation of shareable libraries to allow the dynamic loading of the C code as needed.

  • The use of SCAN_GLOBALS_FOR_OPTION.COM and JAVA$BUILD_OPTION.EXE to dynamically create the .OPT files needed for linking the shareable libraries.

To obtain and use the example:

  1. Restore the save set:

    $ BACKUP -
    SYS$COMMON:[JAVA$14x.VMS_DEMO]INVOKE_JAVA_FROM_C_EXAMPLE.SAV/SAVE [...]*.*

  2. Go to the example directory created by BACKUP:

    $ SET DEFAULT [.INVOKE_JAVA_FROM_C]

  3. Set up your Java environment, e.g.,

    $ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP.COM

  4. Read/Execute the command procedure that builds the example from scratch and executes it. Note: You will first need to update the procedure to reflect the version of the Java environment you are running.

    $ @JNIINVTEST.COM

For information on handling procedure names longer than 31 characters, see the Name-Shortening Capability section.

Name-Shortening Capability

The RTE for OpenVMS can shorten long procedure names (more than 31 characters) using the same translation algorithm used by the C/C++ compilers from HP. To use this feature, compile your C/C++ code with the /NAMES=(AS_IS,SHORTENED) qualifier.

The old name-shortening method using SCAN_FOR_31_CHARS.COM is still supported; you can choose either method. (For information on using SCAN_FOR_31_CHARS.COM, included in the JNI_EXAMPLE.SAV save set, follow the instructions in the Calling C Code from Java Code section, and then read the files JNI_README.TXT, JNI_EXAMPLE.COM, and SCAN_FOR_31_CHARS.COM. You can run SCAN_FOR_31_CHARS.COM manually to produce .H files that redefine the oversized name to be 31 characters.) The names produced in this way are different from those produced by the C/C++ compilers.

When the RTE is confronted with an oversized name, it first tries to find a match using the new compiler-based name compression algorithm — the same one used by running the C or C++ compiler with the /NAMES=(AS_IS,SHORTENED) qualifier.

If the RTE fails to find such a match, it then tries to create a short name using the algorithm used by SCAN_FOR_31_CHARS.COM.

Although the old manual name-shortening method will continue to work, we encourage you to take advantage of the new, more automatic method.

Back to top
Limited File-Sharing Support

The RTE supports limited file-sharing and has several user-selectable modes of file sharing. To enable RTE file-sharing modes, define the logical JAVA$FILE_OPEN_MODE to any of the following values:

0 or not defined

no file sharing

2

sync writes, every write to a file, the file is sync with the disk.

Note: A sync for every write gives you file sharing close to what the SDK expects. However, things that normally took seconds to run, can take minutes or longer.

3

A table of all open file descriptors is kept by the SDK. The SDK then monitors when an application writes to a file, and sets a write_pending flag. Before every read operation the SDK scans the list of open file descriptors. If a match is found with a write pending, the pending write is flushed to the disk before the read.

Limitations: only one process can share the file reliably.

We are working with HP C engineering to enhance the file-sharing features in the C RTL and the SDK.

Back to top
Extended File Specifications

OpenVMS supports Extended File Specifications, which comprise two parts: deep directory nesting and extended file names. See OpenVMS Guide to Extended File Specifications for more information. The RTE can take advantage of both of these capabilities, particularly the extended file names on an ODS-5 disk, which allow much longer file names and mixed-case file names.

To activate this support:

  1. Execute the following command:
    $ SET PROCESS/PARSE_STYLE=EXTENDED

    This command preserves the case of the arguments on the command line, and must be enabled to take advantage of C RTL changes.

  2. Enable the new features of the C RTL by defining special logical names. These logical names are in the JAVA$14x_SETUP.COM file, where they are commented out by default, and where x is the specific version number of the release you are using. The two of interest here are DECC$ARGV_PARSE_STYLE and DECC$EFS_CASE_PRESERVE, which are discussed in the following steps.

  3. Enable DECC$ARGV_PARSE_STYLE to cause the C RTL to preserve the case of command-line arguments (instead of converting them to lowercase):

    $ DEFINE DECC$ARGV_PARSE_STYLE ENABLE

  4. Enable DECC$EFS_CASE_PRESERVE to cause the C RTL to preserve the case of file names in all C RTL I/O functions:

    $ DEFINE DECC$EFS_CASE_PRESERVE ENABLE

With this support enabled, the file "Foo.java" compiles to "Foo.class" instead of "FOO.CLASS".

To disable this feature, issue any one of the following commands:

$ SET PROCESS/PARSE_STYLE=TRADITIONAL
$ DEFINE DECC$ARGV_PARSE_STYLE DISABLE
$ DEASSIGN DECC$ARGV_PARSE_STYLE
$ DEFINE DECC$EFS_CASE_PRESERVE DISABLE

The values for the DECC$ARGV_PARSE_STYLE and DECC$EFS_CASE_PRESERVE logicals are case-insensitive.

Another notable C RTL feature logical name is DECC$EFS_CHARSET. With DECC$EFS_CHARSET enabled, filenames can contain ODS-5 extended characters, including multiple dots. For your Java application to take advantage of this, you must enable DECC$EFS_CHARSET and define JAVA$FILENAME_CONTROLS with only the appropriate bits turned on. For example, if you wish to allow directory and file names that have multiple dots, do the following:

  1. Execute the following command:

    $ SET PROCESS/PARSE_STYLE=EXTENDED

  2. Edit JAVA$FILENAME_CONTROLS.COM and set option_string to only the bits you need:

    option_string = JAVA$M_UNIX_AND_VMS

    In particular, in this example of allowing directory and file names that have multiple dots, do not set the following bits:

    JAVA$M_HIDDEN_WITH_UNDERSCORE
    JAVA$M_HIDDEN_REMOVE_DOT
    JAVA$M_DOT_IN_DIRNAME_UNDER
    JAVA$M_DOT_IN_DIRNAME_REMOVE
    JAVA$M_MULTI_DOT_KEEP_LAST
    JAVA$M_MULTI_DOT_KEEP_FIRST

  3. Execute JAVA$FILENAME_CONTROLS.COM to define JAVA$FILENAME_CONTROLS.

  4. Enable DECC$EFS_CHARSET to cause the C RTL to support ODS-5 extended characters.

    $ DEFINE DECC$EFS_CHARSET ENABLE

For more information on DECC$ARGV_PARSE_STYLE, DECC$EFS_CASE_PRESERVE, DECC$EFS_CHARSET and other C RTL feature switches that can be enabled or disabled using DECC$ logical names, refer to Enabling HP C RTL Features Using Feature Logical Names in the HP C Run-Time Library Reference Manual for OpenVMS Systems.

Back to top
Automatically Determining Case of JAVAC and JAR File Operands

Previously, HP had added the capability for the JAVAC and JAR commands to accept wild-carded file specifications and would automatically determine the right case of the name. This allowed you to say:

$ JAVAC *.java

and

$ JAR cvf test.jar *.class

SDK v 1.3.1 extended this capability in these two tools for any .java (for JAVAC) and .class (for JAR) file operand, so you could say, e.g.,

$ JAR cvf test.jar TESTPLOT.CLASS

and not worry whether it really should be:

$ JAR cvf test.jar "TestPlot.class"

$ JAR cvf test.jar "TESTPLOT.CLASS" 

or

$ JAR cvf test.jar "testplot.class"

This can be particularly helpful to those using DCL to automatically generate operands, because DCL will uppercase them. In general, this reduces the number of situations where you need to present the exact-cased name and quote it.

Note: This works only for JAVAC and JAR. You still need to use the right case for verbs like JAVA itself.

This feature is enabled by default; if it causes troubles with existing command procedures, it can be entirely disabled by setting:

$ define JAVA$OMIT_CASE_CHECK true

If the command procedures you use have properly cased operands, HP recommends you turn off this automatic case checking; it slows down operations.

Back to top
Enabling UNIX-Style Behavior in Certain File-Manipulation Commands

The following logical names enable UNIX-style behavior for certain file-manipulation commands:

$ define JAVA$DELETE_ALL_VERSIONS true
(on delete, delete all versions)

$ define JAVA$RENAME_ALL_VERSIONS true
(on rename, rename all versions)

$ define JAVA$CREATE_DIR_WITH_OWNER_DELETE true
(on directory creation, establish O:REWD protection as default)

The DECC$FILE_PERMISSION_UNIX logical name supercedes the effects of JAVA$CREATE_DIR_WITH_OWNER_DELETE.

On OpenVMS, if you type:

mkdir("a/b/c", mode)

and later:

chmod("a/b/c", mode)

only the directory 'c' gets the new mode.

By turning on the DECC$FILE_PERMISSION_UNIX logical name, the directories 'a' and 'b' are affected by the new mode as well.

For more information, refer to Enabling HP C RTL Features Using Feature Logical Names in the HP C
Run-Time Library Reference Manual for OpenVMS Systems
.

Back to top
Correspondence Between Directory Info in _java.policy and Default Directory

You must have a direct correspondence between the way you specify a directory in a _java.policy file and your current directory when used as part of the CLASSPATH. (Your current default directory is always part of your implied classpath.)

For example, if your policy file says:

grant codeBase "file:${rootdir}/-" {
permission java.security.AllPermission;
};

and you invoke your application (in part) as:

$ java -Drootdir=/DISK1$/directory/subdirectory/

you must get to that directory via:

$ SET DEF DISK1$:[directory.subdirectory]

You cannot use an alias such as:

$ SET DEF USER1$:[directory.subdirectory]

even if USER1$ is the same disk as DISK1$, because the entire permission process (to determine allowable access) is based on the comparison of file specification strings. From a string-comparison standpoint (even case-blind), USER1$:[directory.subdirectory] is not the same path as DISK$1:[directory.subdirectory], and access will be denied.

Back to top

Application Performance Tuning

You can optimize the performance of your application on OpenVMS in several ways, without changing your application code. The RTE is sensitive to the existence of a certain logicals that will alter its behavior. The following descriptions offer several techniques you can use to optimize performance. You can also refer to Optimizing Java Technology Software Performance on OpenVMS for tips on improving Java performance on OpenVMS systems.

First Technique: Using JAVA$FORK_MAILBOX_MESSAGES, JAVA$EXEC_USE_PIPES, and JAVA$FORK_PIPE_STYLE

Applications can be tuned for performance using the logical JAVA$FORK_MAILBOX_MESSAGES and JAVA$EXEC_USE_PIPES.

On OpenVMS systems, Java process creation and parent-child relationships are managed by native threads. If they pass data between them it is done by mailboxes. For example, in a typical scenario, a child process produces a stream of output, and the parent process consumes this stream as input.

Schematically,

    
    Child Writes
         |
         V
      Mailbox
         |
         V
    Parent Reads
    

Some applications are written such that the parent starts off the child and then waits for the child to finish before starting to read its stream of data. In others applications, the parent starts reading as soon as it can, but cannot keep up with the child. Both of these approaches can get into trouble.

The trouble arises because the mailboxes are of a finite size.

If the mailbox fills up, the child is blocked from doing further work and never gets done. Meanwhile, the parent is waiting for the child to finish, and also cannot proceed. This state is known as a Read-Write MailBoX (RWMBX) wait state (or RWINS), and the process running this application is blocked.

To try to avoid this situation, the RTE does buffering between the mailbox and the consumer. One thread reads data from the mailbox and stores it in heap storage. Another thread reads buffered data from this heap and delivers it to the parent when it asks for it.

Schematically:

    
    Child Writes
         |
         V
      Mailbox
         |
         V
    PutToHeap
         |
         V
    GetFrom Heap
         |
         V
      Mailbox
         |
         V
    (Java application)Parent Reads
    

In the case where the parent is waiting for the child to finish, this buffering may empty the mailbox enough so that the child can continue to run and finish, thereby freeing the parent to continue as well. In the case where the parent is continually reading but is temporarily being overwhelmed, the buffering smooths the production-consumption data flow.

If the parent is really waiting for the child to complete before consuming any of the information stream, this buffering mechanism itself starts to fail when the volume of output exceeds the amount of heap storage available. When no more heap is available, PutToHeap cannot empty the Mailbox, and again you face (RWMBX or RWINS) wait state. The blocked state persists unless some asynchronous agent comes along and changes the resources involved; for example, releasing some heap storage.

In most cases, however, the added capacity of heap storage is enough for the child to complete and the parent to continue.

As a further enhancement to control this data flow, we monitor the pipeline for how many messages are outstanding.

Schematically:

          +--------->Child Writes
          |                |
          |                V
          |            Mailbox
    count                  |
    messages               |
    outstanding            V
          |          PutToHeap
          |                |
          |                V
          +---------->GetFrom Heap
                           |
                           V
                         Mailbox
                           |
                           V
          (Java application)Parent Reads
    

When the number of messages written exceeds the number read by an amount equal to the lesser of 1024 and the value of the logical JAVA$FORK_MAILBOX_MESSAGES, then we stop the writes to prevent the RWMBX condition. JAVA$FORK_MAILBOX_MESSAGES is assumed to be 8 if not defined.

This temporary curtailment of production allows the parent thread to catch up (get within the exceeded message threshold), and the overall application continues.

As previously mentioned, if JAVA$FORK_MAILBOX_MESSAGES is not defined, it is assumed to be 8. With this value in control, anytime the writer gets 8 records ahead of the consumer, the writer is temporarily suspended. For applications that produce many small records, try setting a value of JAVA$FORK_MAILBOX_MESSAGES to a larger value -- perhaps 1024 divided by your typical mailbox record size. The bigger you can make it -- think of it as a blocking factor -- the more efficient the operation becomes because you are minimizing the start-stop time of the producer thread. If you make it too large, you might induce the RWMBX state. If you see the Java application in RWMBX state for a while without having explicitly used JAVA$FORK_MAILBOX_MESSAGES, try setting it to a value less than the default value of 8.

You can revert to unbuffered behavior for exec and pipes by defining the logical JAVA$EXEC_USE_PIPES.

$ DEFINE JAVA$EXEC_USE_PIPES 1 ! use unbuffered behavior

The logical name JAVA$FORK_PIPE_STYLE is available to augment the features offered by JAVA$EXEC_USE_PIPES. You can choose among three styles of data flow management:

Value for JAVA$FORK_PIPE_STYLE

Behavior

Same As...

0

Use unbuffered behavior

JAVA$EXEC_USE_PIPES = 1

1

Default behavior

JAVA$EXEC_USE_PIPES undefined

2

Default behavior, except uses a socket rather than a mailbox for buffering data between the heap and the Java application Parent Reads (requires a TCP/IP stack)

JAVA$EXEC_USE_PIPES undefined, except uses a socket rather than a mailbox for buffering data between the heap and the Java application Parent Reads (requires a TCP/IP stack)


Defining JAVA$FORK_PIPE_STYLE with the value 0 is the same as defining JAVA$EXEC_USE_PIPES with the value 1. The result is that the unbuffered behavior is used.

Defining JAVA$FORK_PIPE_STYLE with the value 1 is the same as NOT defining JAVA$EXEC_USE_PIPES. The result is the buffered behavior described in the previous paragraphs.

Defining JAVA$FORK_PIPE_STYLE with the value of 2 is similar to NOT defining JAVA$EXEC_USE_PIPES, but will result in the use of a socket rather than a mailbox for buffering data between the heap and the Java application Parent Reads. Note: This style requires a TCP/IP stack.

Schematically:

    
    Child Writes
         |
         V
    Mailbox
         |
         V
    PutToHeap
         |
         V
    GetFrom Heap
         |
         V
    Socket
         |
         V
    (Java application)
    Parent Reads
    

Because the Java application is reading from a socket device, it can use nonbuffered IO, ioctl features, cancel IO operations, etc. It is the closest to simulating true UNIX pipe functionality. Processing data from the child using this style results in a performance improvement.

Second Technique: Using JAVA$DISABLE_MULTIDOT_DIRECTORY_STAT

Avoiding Secondary stat() Call

Because of the way File Name Mapping works, and the way in which directories that contain dots are handled on OpenVMS, the RTE may need to do an extra stat() call whenever you seek a class file that is not found on the initial stat() call.

Suppose you import an application from another platform that has within its overall directory structure a directory named project-3.1-A.

During operation you may need to verify that the directory exists. On OpenVMS you cannot yet represent a directory named project-3.1-A. As a result, if the application attempts to see if the directory exists, the RTE will first try to access via stat(): projects/project-3.1-A.

When that fails, it will do another stat() wherein the path has been modified to remove all dots from directory names: projects/project-3_1-A.

Because this second attempt is needed to support remapping of directories that contain "dot(s)," any failed stat() will result in a second call to stat() to attempt to see if it is a directory containing a "dot(s)."

In general, whenever a stat() call fails, the RTE attempts another stat() call with a potentially modified path name.

What Is the Impact of Doing a Second stat() Call?

Modern Java applications are typically constructed by drawing together class files (libraries) provided by a number of vendors. In order to tie this together at runtime, you must specifiy long Classpath strings that can contain hundreds of individual path names.

For example, for projects/classes/MyApp.class, the RTE would try to stat() "projects/classes/MyApp.class" first; if that fails, it would try "projects/classes/MyApp_class" to see if it is a directory that contains any "dot(s)."

If you are looking for a particular class file, you will generally need to look through approximately 50 percent of the paths to find the one you need; this means that the RTE will do two stat()s for every class file lookup failure.

Each time you look on a path that does not contain the sought class, the failure of the stat() causes a secondary stat() to be issued. If you multiply these secondary stat() calls by the several hundred classes that are loaded during a typical application you can see that the total number of secondary stat() calls can account for a significant amount of application start up.

However, if you know that your application never deals with directories that have dots in their names, you can now tell the RTE not to do the secondary stat() call because it will have no value to your application.

This is accomplished by setting:

$ define/nolog JAVA$DISABLE_MULTIDOT_DIRECTORY_STAT true

This will disable the secondary stat() call.

Realize, however, that if you turn on this logical and your application does attempt to find something in a directory that originally had dots in it, your application will fail, probably by throwing a java.lang.NoClassDefFoundError or Directory error.

Third Technique: Using JAVA$CACHING_INTERVAL

Some applications spend considerable time creating files, monitoring directories for the existence of files, and testing properties of files using file methods such as:

File file = new File(name);
file.exists()
file.isDirectory()
file.isAbsolute()

These methods indirectly use the underlying C Run-Time Library stat() function.

A typical sequence might appear as:

if (file.exists()) { // ends up calling stat()
if (file.isDirectory()){ // ends up calling stat() again
...
}
}

If your application does these kinds of operations--continuous polling for changes in a monitored set of files--you might benefit from this optimization.

If you define a logical,

$ DEFINE/JOB JAVA$CACHING_INTERVAL <caching interval in seconds>

e.g.,

$ DEFINE/JOB JAVA$CACHING_INTERVAL 60

then the information gathered by the stat() function is cached for the interval indicated before it is deemed stale and the cache is invalidated.

Hence, in the code fragment above, the question file.isDirectory()is answered from cached information and no I/O is actually performed. This represents a considerable difference in time. Some web servers have been observed making hundreds of calls per second to monitor the status of the same group of files. The overall speed-up in such cases can be dramatic.

Additional caching occurs when JAVA$CACHING_INTERVAL is enabled and JAVA$CACHING_DIRECTORY defined; the caching algorithm will attempt to discover the reason a file is "not found". If it is because a directory tree does not exist, the caching algorithm will be optimized to recognize that future attempts to this tree will also fail (until the directory has been created). This improves application startup for an application that has several directories defined in JAVA$CLASSPATH (or CLASSPATH).

The cache is invalidated and a real call to stat() is made the first time after:

  • The current caching interval expires.


  • An explicit action is taken within the current application that may be assumed to change the validity of the cached information, including:

    • A file is opened for something other than READ.


    • A file or directory is created or destroyed.


    • A child process is spawned via Runtime.exec() or completes.

The main drawback to this caching is that if another application, without the cooperation of this application (e.g., FTP), copies a file into the monitored set, the RTE might not see it until the cache is invalidated for one of the reasons above.

By default, this optimization is not enabled. You can enable it only by setting the logical JAVA$CACHING_INTERVAL to a positive non-zero value.

Fourth Technique: Using JAVA$DAEMONIZE_MAIN_THREAD

With applications that make heavy use of ASTs, the main Java thread could be starved for CPU time.

As described in section B.12.5, Delivery of ASTs, in the Guide to the POSIX Threads Library:

In addition to per-thread ASTs, there are also user mode ASTs that are directed to the process as a whole, or to no thread in particular, or to a thread that has since terminated. These "process" ASTs are queued to the initial thread, making the thread runnable in a fashion similar to per-thread ASTs. They are executed in the context of the initial thread ....

Later, the same section describes how, among the implications that must be considered for application development:

If an application makes heavy use of ASTs, it can starve the initial thread to a degree, because only that thread executes the ASTs that are directed to the entire process.

In other words, "process" ASTs are executed first, and the Java thread running in the main thread only gets the CPU if there are not any ASTs. If you define a logical,

$ define JAVA$DAEMONIZE_MAIN_THREAD true

a new thread is created to run the main Java thread. In applications that make heavy use of ASTs, this allows ASTs to use a CPU without starving the main Java thread.

Without JAVA$DAEMONIZE_MAIN_THREAD defined, the main Java thread shares a CPU with ASTs. With JAVA$DAEMONIZE_MAIN_THREAD defined, the main Java thread is an empty thread allowing it to handle only ASTs. The real main Java thread is moved to another thread. On a multi-CPU system, the main thread could be running on one thread and the ASTs could be running on another thread.

Fifth Technique: Using JAVA$READDIR_CASE_DISABLE

This logical name allows the user to turn off the case-sensitive filename extraction feature (ODS-2 “auto case” correction for “readdir” entries) if it is not needed:

$ define JAVA$READDIR_CASE_DISABLE true

If you use the Java method File.list() and JAVA$READDIR_CASE_DISABLE is not defined (by default it is not defined), the RTE will ensure that all directory lookups for .java or .class filename entries will have the correct case. For example, if the properly cased filename is Foobar.class, on an ODS-2 disk structure, the filename will be stored as FOOBAR.CLASS. By default, the RTE will ensure the internal view of the filename is Foobar.class. If you can restrict all your files to an ODS-5 disk structure and ensure the filenames are created/named with the correct case, defining JAVA$READDIR_CASE_DISABLE will increase the performance of scanning directories that contain *.java and *.class filenames.

Sixth Technique: Using JAVA$OMIT_CASE_CHECK

This logical name allows the user to turn off the automatic determination of the case of JAVAC and JAR file operands.

$ define JAVA$OMIT_CASE_CHECK true

If you use the JAVAC or JAR command and JAVA$OMIT_CASE_CHECK is not defined (by default it is not defined), the RTE will automatically determine the correct case of .java and .class file operands, as described in Automatically Determining Case of JAVAC and JAR File Operands. If you can restrict all your files to an ODS-5 disk structure and ensure the filenames are created/named with the correct case, defining JAVA$OMIT_CASE_CHECK will increase the performance of the JAVAC and JAR commands.

Seventh Technique: Displaying Graphics-Intensive Applications

When displaying graphics-intensive Java applications on remote host displays (via TCP/IP), setting the Java property sun.java2d.pmoffscreen to false may significantly increase the application's graphics performance. This property is set via the Java command line, e.g.,

-Dsun.java2d.pmoffscreen=false

For further information, see Runtime Flag for Solaris and Linux on Sun's site.

Eighth Technique: Using JAVA$TIMED_READ_USE_QIO

Some Web applications spend considerable time using Socket Streams with timeout values. Because of this, the virtual machine makes use of C Run-Time Library's select() function in a multi-thread nature. If the logical JAVA$TIMED_READ_USE_QIO is enabled, the virtual machine will use QIO(s) and AST(s) to implement the same functionality as select(). The major result has been a reduction of overall kernel mode CPU usage, giving the application more available user mode CPU power.

If you are running TCP/IP Services for OpenVMS, you can use the command tcpip show comm/mem to determine if your application might benefit from using this logical.

Capture a baseline for the number TCPIP Timer and Select structures before starting the application.

$ tcpip show comm/mem
...

8 mbufs allocated to OpenVMS TCPIP Timer structure
3 mbufs allocated to OpenVMS LAN VCI VCIB structure
1 mbufs allocated to OpenVMS LAN MCAST_REQ structure
2 mbufs allocated to OpenVMS SELECT structure

...

Continue to monitor these values as the application is stressed.

$ tcpip show comm/mem
...

30 mbufs allocated to OpenVMS TCPIP Timer structure
3 mbufs allocated to OpenVMS LAN VCI VCIB structure
1 mbufs allocated to OpenVMS LAN MCAST_REQ structure
24 mbufs allocated to OpenVMS SELECT structure

...

If the mbuf "Select" structure count is double digits, your application could benefit from this logical.

You can monitor the overall system performance improvement. The system will use less Kernel and Executive Mode CPU.

Before:

$ monitor system/all

                               SYSTEM STATISTICS
                                 on node SECURE
                            12-MAY-2003 15:22:19.28

                                       CUR        AVE        MIN        MAX

    Interrupt State                  16.33      15.80      14.83      16.33
    MP Synchronization                5.33       5.19       4.16       5.66
    Kernel Mode                      80.83      80.73      77.66      84.66
    Executive Mode                   20.50      20.16      18.83      20.66

    Supervisor Mode                   0.00       0.00       0.00       0.00
    User Mode                        94.16      95.03      90.83      99.00
    Compatibility Mode                0.00       0.00       0.00       0.00
    Idle Time                       183.16     183.03     175.50     191.83


After:


                             SYSTEM STATISTICS
                                 on node SECURE
                            12-MAY-2003 15:38:44.41

                                       CUR        AVE        MIN        MAX

    Interrupt State                  16.50      17.95      16.50      20.16
    MP Synchronization                4.00       4.25       4.00       4.83
    Kernel Mode                      32.83      35.87      32.83      41.33
    Executive Mode                    1.00       0.50       0.00       1.00

    Supervisor Mode                   0.00       0.00       0.00       0.00
    User Mode                        75.00      77.95      72.83      87.00
    Compatibility Mode                0.00       0.00       0.00       0.00
    Idle Time                       270.83     263.62     246.83     270.83

Note: The major benefit was a decrease in CPU usage. This test case also handled 33% more transactions than the "Before" test.

Back to top
Supporting VAXC$PATH

You can use VAXC$PATH as an OpenVMS search path for locating .EXE or .COM files outside the default directory. Using SDK v 1.4.1 as an example,

$ define VAXC$PATH GNU:[bin],[],sys$common:[JAVA$141.bin] ! open source GNU files

br = new BufferedReader(new InputStreamReader(
rt.exec("chmod").getInputStream()));

The above will now search the three directories defined in VAXC$PATH for chmod., chmod.exe, or chmod.com. Also,

br = new BufferedReader(new InputStreamReader(
rt.exec("javac").getInputStream()));

The above will search for javac., javac.exe, or javac.com.

Back to top
Enabling Correct Operation of File (fname) when fname Is a Logical or a Disk Name

Note: This is an incompatible change to behavior in SDK v 1.3.1-1 for OpenVMS Alpha.

SDK v 1.3.1-1 fixed a problem that occurred when you tried to open a file using rooted logicals such as:

File f = new File ("/sys$sysroot");

A problem would occur if you attempted to get a directory listing of rooted logicals, (e.g., sys$sysroot) or of disk names (e.g., "/sys$sysdevice" or "/node$dka200"). With the current C RTL the RTE must internally add a "/000000" to these names to make this directory listing operation work correctly.

This workaround created problems with nonrooted logicals like "/sys$errorlog". HP expects that newer C RTLs will handle these special cases internally and the RTE will no longer need to use this workaround. Anticipating this transition, we have removed the automatic addition of "/000000" as the default behavior. If you still need this capability in your application with the current C RTL you must explicitly request it by defining a logical:

$ define/job JAVA$ENABLE_ROOT_WITH_000000 TRUE

Back to top
Working with Runtime.exec()


Using SET VERIFY

Using SET VERIFY with exec does not work. If verification is on, then the Java application will hang. There is no workaround, except to ensure that verification is off.

Using the Runtime.exec() Method on OpenVMS

Note: The logical name JAVA$EXEC_TRACE is available to help debug Runtime.exec() calls on OpenVMS. Refer to JAVA$EXEC_TRACE in Debugging Tools for more information on this and other diagnostic tools.

Normally, the argument passed to exec is the name of the image to be executed. But there are some instances where this does not work:

Asking a Java program to exec a DCL verb like DIR does not work.

Workaround:

Pass as the argument to exec, the OpenVMS-style filename of a .COM file that contains the DCL verb to be executed (or that builds the verb from input parameters to the .COM file).

Asking a Java program to exec a .COM file specified as a UNIX-style filename with a leading slash does not work.

Alternative Workarounds:

  • Use an .exe file.


  • Use the OpenVMS-style filename for a .COM file.


  • Define a symbol for the absolute part of the path in OpenVMS-style, and prepend that symbol to the UNIX-style filename, thus eliminating the leading slash in the UNIX-style filename. (See the sample program that follows.)

The following sample program shows what kinds of constructs work, and which ones do not:


import java.io.*;

public class ExecTest {

   public static void main(String args[]) {
      int i;
      Runtime rt = Runtime.getRuntime();
      String[] cmdarray =
      {
      // Tests involving .COM files
      // --------------------------
      //
      //  pass simple args to local .com
      "display_args.com 3 4", //works

      //  pass args that need to be quoted to local .com
      "display_args.com a/b/c  4",  //works -- but a/b/c will be
                                    //         upcased to AB/C

      //  pass args that need to be quoted to local .com
      "display_args.com \"a/b/c\"  4",  //works -- arg is quoted

      // no path, name of .com without .com extension
      "five_testing",               //works

      // no path, name of .com with .com extension
      "TEST_IEEE.com",              //works

      // VMS filespec path, name of .com with .com extension
      "user1$:[reichert.sanity_test]five_testing.com",  //works

      // UNIX-style filespec path, name of .com
      // with .com extension
      "/user1$/reichert/sanity_test/five_testing.com",
                     //fails %DCL-W-IVQUAL, unrecognized qualifier
                     //Due to leading '/' on .com filespec

      // UNIX-style filespec path, name of .com
      // without .com extension
      "/user1$/reichert/sanity_test/five_testing",
                     //fails %DCL-W-IVQUAL, unrecognized qualifier
                     //Due to leading '/' on .com filespec

      // UNIX-style filespec path, name of .com
      // without .com extension
      // absolute path using a logical to avoid the leading '/'
      "my_dir/five_testing",
                     //works -- because my_dir is a logical:
                     // $ sho log my_dir
                     // "MY_DIR" = "USER1$:[REICHERT.SANITY_TEST]"

      // VMS-style filespec path, name of .com
      // with .com extension -- write a file
      "user1$:[reichert.sanity_test]file_writer.com",   // works

      // Tests involving DCL verbs
      // --------------------------
      //

      // Trying to execute a DCL verb
      "SHOW LOG *INCLUDE* ",
                     // fails - can't execute a DCL verb.

      // Trying to execute a .EXE that corresponds to a verb
      // "SYS$COMMON:[SYSEXE]DIRECTORY.EXE ",
                     // fails - it will loop with no output.
                     // You have to put commands in a .COM file
                     // and execute that.

      // execute .com with the "SHOW LOG *INCLUDE* " in it
      "show_logical.com",                      //works

      // Tests involving .EXE files
      // --------------------------
      //

      // UNIX-style filespec path, name of .exe
      // with .exe extension
      "/user1$/reichert/sanity_test/TEST_IEEE.EXE",  //works

      // Induce an error to test reading of sys$error
      //
      "TYPE_OUT_NONEXISTANT_FILE.COM"                //

      };

      // output from the process comes in on
      // br.readLine
      BufferedReader br;

      // error output from the process comes in on
      // error_br.readLine
      BufferedReader error_br;

      // execute the external file
      for (i=0; i<cmdarray.length; i++) {

         try {
         System.out.println();
         System.out.println("Executing string: " + cmdarray[i]);

            Process proc = rt.exec(cmdarray[i]);

            br = new BufferedReader(new InputStreamReader(
                    proc.getInputStream()));

            error_br = new BufferedReader(new InputStreamReader(
                    proc.getErrorStream()));

            String line;

            System.out.println(
            "### Following lines came back from SYS$OUTPUT:");

            // Read back normal output
            //
            while ((line = br.readLine()) != null) {
                    System.out.println(line);
            }       // end while
            br.close();        // close the data input stream


            System.out.println(
            "### Following lines came back from SYS$ERROR:");

            // Read back error output
            //
            while ((line = error_br.readLine()) != null) {
                    System.out.println(line);
            }       // end while
            error_br.close();  // close the data error stream
           // Explicitly close streams to avoid exhausting bytlm
           //
            proc.getInputStream().close();
            proc.getErrorStream().close();

         } catch (IOException e) {
                 e.printStackTrace();
         }  // end catch
      }

   System.out.println("*** End of ExecTest ***");

   }  // end main

}       // end ExecTest

Back to top
itanium only I64 Implementation


Using the HotSpot VM and Setting Up the Java Environment

As noted in the Introduction, the SDK for Itanium contains the HotSpot Virtual Machine. The HotSpot runtime compiler technology is designed to provide optimal Java runtime performance on OpenVMS I64 systems. The following sections describe how to control the HotSpot VM.

Note: For simplicity, this document assumes you installed the SDK using the default location and therefore references SYS$COMMON:[JAVA$14x] throughout the text. However, if you specified a destination and installed the kit in that alternate location, substitute that location for the default while reading this document.

You select which VM to use when you set up your Java environment. To set up your environment, use the following command:

$ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP !  Use the HotSpot VM

where x is the specific version number of the release you are using.

Verify your Java environment by typing the java -version command. The screen displays the following message:

$ java -version
java version "1.4.x"
Java(TM) 2 Runtime Environment, Standard Edition
HotSpot VM (build 1.4.x-n ...)

where x is the specific version number of the release you are using, n identifies the specific update release that is installed, and HotSpot VM identifies the virtual machine.

After setting up the Java environment, you invoke the SDK with the java command:

java
Usage: java [-options] class [args...]
...

Any arguments that appear after class name on the command line are passed to the main method of the class.

For information on switching versions in separate processes, or in the same process, refer to Switching Versions.

HotSpot VM Support

  • The HotSpot VM for I64 systems does not support the Java VM Debugging Interface (JVMDI), the Java Platform Debugger Architecture (JPDA), and the Java VM Profiling Interface (JVMPI).

Non-standard Options

The HotSpot technology in SDK 1.4.x accepts the following partial list of non-standard -X and -XX options as described on Sun's site. Non-standard options are not guaranteed to be supported on all VM implementations, and are subject to change without notice in subsequent releases of the SDK.

Option

Function

-verbosegc or -verbose:gc

Prints out the result of a garbage collection to the stdout stream.

-X Prints out a brief usage message describing the non-standard options.
-Xbatch Disables background compilation. If compilation of a large method is taking a long time, the performance engine will revert to interpreting the method. It will compile the method as a background task, running the method in interpreter mode until the background compilation is finished. The -Xbatch flag disables background compilation so that compilation of all methods proceeds as a foreground task until completed, regardless of how long the compilation takes. This flag is provided for users who desire more deterministic behavior of method compilation for purposes such as benchmarking.

-Xbootclasspath:<bootclasspath>

Specify a colon-separated list of directories, JAR archives, and ZIP archives to search for boot class files. The specified boot class libraries will be used instead of the boot class files in the jre/lib/rt.jar archive normally used by the Java 2 software.

-XheapInitialSizes Use to see the default value for the Java Heap.
-Xincgc Enables the incremental garbage collector. The incremental garbage collector, which is off by default, will eliminate occasional garbage-collection pauses during program execution. However, it can lead to a roughly 10% decrease in overall performance.
-Xint Operate in interpreted-only mode. Compilation to native code is disabled, and all bytecodes are executed by the interpreter. The performance benefits offered by the Java HotSpot adaptive compiler will not be present in this mode.
-Xmn Set the Java new generation heap size (for example: -Xmn64m). The new generation is the first generation in HotSpot's generational garbage collector. This option replaces the option -XX:NewSize=N.
-Xms<size> Specify the initial size, in bytes, of the memory allocation pool. This value must be a multiple of 1024 greater than 1 MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 5248KB.
-Xmx Specify the maximum size, in bytes, of the memory allocation pool. This value must be a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 64 MB.
-Xnoclassgc Disables class garbage collection.
-Xoptgc This optimistic garbage collection flag improves garbage collection performance of applications with mostly short-lived objects. A server-side application that creates many short-lived objects for each transaction is likely to benefit greatly with -Xoptgc. However this flag should be used with caution. It is not recommended for applications that build up objects quickly during the run time that are not short-lived.
-Xprof Profiles the running program, and sends profiling data to standard output.
-Xss<size> Specifies the size of stack for each new Java thread. The default Java thread stack size is 128KB. Program threads that overflow the allocated stack will receive java.lang.StackOverFlowException.
-XX:+AggressiveHeap Instructs the JVM to push memory use to the limit. It sets the overall heap to around 1500 MB, the memory management policy defers collection as long as possible, and some GC activity is done in parallel. Because this option sets heap size, do not use the -Xms or -Xmx options in conjunction with -XX:+AggressiveHeap. Doing so will cause the options to override each other's settings for heap size.
-XX:+DisableExplicitGC Disable calls to System.gc(). The JVM still performs garbage collection when necessary.
-XX:MaxNewSize=<size> Sets the maximum size of new generation (in bytes).
-XX:NewSize=<size> Sets the default size of new generation (in bytes).
-XX:NewSizeThreadIncrease=<sizeInKb> Sets the additional size added to desired new generation size per non-daemon thread (in bytes).
-XX:MaxPermSize=<size> Sets the maximum size of permanent generation (in bytes).
-XX:PermSize=<size> Specifies the initial size, in bytes, of the Permanent Space memory allocation pool. This value must be a multiple of 1024 greater than 1 MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. Default for SDK v 1.4.x is: -XX:PermSize=16m.
-XX:+ServerApp A set of XX options which, when bundled together, make some applications run faster. For each release, the options as well as the values may be different depending upon the default values of XX options. We recommend that you test to see whether this set enhances the performance of your application before you use the option in production.
-XX:+UseConcMarkSweepGC Use the concurrent low pause garbage collector. This collector uses a separate collector thread to do parts of old generation collection concurrently with the application threads. A parallel version of the new generation collector is used as well, to further reduce pause times.
-XX:+UseParallelGC Use parallel garbage collection, can improve the performance of your application on multiprocessor systems, and is strongly recommended for applications using large heaps.
-XX:SurvivorRatio=<size> Ratio of eden/survivor space size. Default for SDK v 1.4.x is 8. If your new generation heap is 100 MB, the space reserved for objects to survive a GC is ½*(100MB/8), or 6.25 MB. Raising this value may improve overall application performance when the new space is large and/or when your application keeps a very low percentage of objects.
 

HP specific Options and Features

Additional HP-specific documentation is provided in the HP-UX Programmer's Guide at http://www.hp.com/products1/unix/java/infolibrary/prog_guide/index.html.

The SDK v 1.4.x release includes the HP specific option, -Xverbosegc, which prints out detailed information about the spaces within the Java heap before and after garbage collection.

The syntax is

-Xverbosegc[:help]|[0|1][:file=[stdout|stderr|<filename>]]

:help prints this message.

0|1 controls the printing of heap information:
   0 Print only after each Old Generation GC or Full GC

   1 (default) Print after every Scavenge and Old Generation GC or Full GC

:file=[stdout|stderr|<filename>] specifies output file
    stderr (default) directs output to standard error stream
  stdout directs output to standard output stream
  <filename> file to which the output will be written

For a detailed explanation of the fields in the -Xverbosegc:help output, see http://www.hp.com/products1/unix/java/infolibrary/prog_guide/xverbosegc_1-4-1.html.

In addition we recommend HP's garbage collection analysis tool HPjtune, which displays information contained in an Xverbosegc log graphically. HPjtune is available at no cost from www.hp.com/go/java.

Tuning and Performance

This section contains information on tuning and performance for the HotSpot VM.

Heap Size Considerations

The maximum size of the Java heap on OpenVMS for Integrity (Itanium) has been extended from 900 MB to 1500 MB.

To take advantage of the larger heap, you may need a larger process Page File Quota. See “Setting Process Quotas for Better Performance on OpenVMS” in the User Guide for guidelines on setting Pgflquo according to your heap size. It is also important to be aware that increasing your heap size takes memory away from other uses. For example, you may not be able to create as many application threads as you could with a smaller heap. This might be addressed by decreasing the per-thread heap size using the -Xss switch. For example, you could decrease the setting from the default -Xss128k down to -Xss64k. However, depending on the nature of your application and what other libraries are used, it might not be possible to use the full 1500 MB now supported. If you have “out of memory” failures even after decreasing the per-thread stack size, you may need to use a smaller heap size.

If you use a large heap and your system has two or more CPUs, it is strongly recommended that you use the parallel garbage collector by specifying "-XX:+UseParallelGC" on your command line. This collector performs multi-threaded collection of "new space," where objects are created, and thus has better scaling properties than the default collector.

Because of the way the heap must be split across the P0 and P1 memory regions on OpenVMS, some adjustments are automatically made to heap management parameters as the heap becomes large.

  • As the heap exceeds 1250 MB, the ratio of "new space" to "old space" size must be shifted toward "new space." Hotspot on OpenVMS will adjust the SurvivorRatio to compensate for this. If you have specified a MaxNewSize or SurvivorRatio on the command line, you may notice it was changed in the output of -XheapInitialSizes.

  • The incremental garbage collector (-Xincgc) is intended to minimize application pause times when garbage collections occur. To help do so, “new space” is kept relatively small. As the heap size exceeds 900 MB, the ideal ratio can no longer be preserved. Hence, -Xincgc will be most effective at eliminating pauses with heap sizes under 900 MB.

Lastly, it is important to remember that a larger heap is not always better, and thus you shouldn’t arbitrarily use a 1500 MB heap. Doing so could unnecessarily lengthen garbage collection times, or increase your page fault rate, and thus decrease performance rather than improving it.

For additional information on performance tuning and memory management, see Tuning garbage collection with the 1.4.2 Java Virtual Machine on Sun's website.

Back to top
alpha only Alpha Implementation


Using the Fast VM and Setting the Java Environment

As noted in the Introduction, the SDK for Alpha contains the Fast Virtual machine and Classic virtual machine. The Fast VM is Just-In-Time (JIT) compiler technology designed to provide optimal Java runtime performance on OpenVMS Alpha systems. The Fast VM offers significant performance advantages over the Classic JIT. The following sections describe how to control the Fast VM.

Note: For simplicity, this document assumes you installed the SDK using the default location and therefore references SYS$COMMON:[JAVA$14x] throughout the text. However, if you specified a destination and installed the kit in that alternate location, substitute that location for the default while reading this document.

You select which VM to use when you set up your Java environment. To set up your environment, use one of the following two commands:

$ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP FAST ! Use the Fast VM
$ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP !  Use the Classic VM

where x is the specific version number of the release you are using.

Verify your Java environment by typing the java -version command. The screen displays the following message:

For the Fast VM:

$ java -version
java version "1.4.x"
Java(TM) 2 Runtime Environment, Standard Edition
Fast VM (build 1.4.x-n ...)

For the Classic VM:

$ java -version
java version "1.4.x"
Java(TM) 2 Runtime Environment, Standard Edition
Classic VM (build 1.4.x-n ...)

where x is the specific version number of the release you are using, n identifies the specific update release that is installed, and Fast VM and Classic VM identifies the virtual machine.

Note: To revert to the Fast VM when using the Classic VM, type the following command:

$ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP FAST

After setting up the Java environment, you invoke the SDK with the java command:

java
Usage: java [-options] class [args...]
...

Any arguments that appear after class name on the command line are passed to the main method of the class.

For information on switching versions in separate processes, or in the same process, refer to Switching Versions.

Fast VM Support

  • The Fast VM uses more memory than the classic VM; therefore, you might need to adjust your quotas or heap size. Refer to
    Memory Usage for more information.

  • The Fast VM does not support the Java Platform Debugger Architecture (JPDA). If you try to debug an application with any
    debugger that uses the JPDA interface, such as jdb, you will see a message stating that the Fast VM does not support
    debugging, and the program will exit. You can use the classic VM for debugging your Java application.

  • Native methods used with the Fast VM must conform to the Java Native Interface (JNI) specification on the Sun site. The
    Fast VM does not support native method conventions older than the JNI specification.

  • The -hotspot option is silently ignored, and the -Xincgc option is not supported. This tuning option is specific to Sun's HotSpot virtual machine.

Standard Options

The java command supports all standard options, as described on Sun's site. SDK v 1.4.x includes the Fast VM, which is designed for high performance on OpenVMS Alpha systems rather than Sun's HotSpot virtual machine. The -hotspot standard option is silently ignored. For more information, refer to I64 Implementation.

Nonstandard Options

By default, the java command supports most non-standard options, as described on Sun's site. The following options are supported by the classic VM and not by the Fast VM: -Xdebug, -Xnoclassgc, and -Xrunhprof. If your application uses one of these options, you must use the classic VM. -Xprof is not supported; however, -Xrunhprof is available for classic VM profiling.

Additional Options

In addition to Sun's options, the java command supports the following options.

Option

Function

-client

Initializes the Fast VM with a maximum heap size of 64 MB, a maximum global region size of 128 MB and the compacting collector. Refer to Reducing Fast VM Memory Requirements for Workstations and Client-Side Applications for more information.

-Xcode<size> The option, -Xcode<size> allows a larger code region for code generated by the Fast VM. Size is the code region maximum allocation size in bytes. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. You can specify values between 24M and 128M. The default value is -Xcode24M.
-Xdynclassgc Instructs the Fast VM to garbage collect the class data for dynamically generated classes when those classes are no longer used. By default, the Fast VM garbage collects only heap objects, not class data structures. Refer to Garbage Collection of Class Data for Dynamically Generated Classes for more information.

-Xglobal<size>

Specifies the global region maximum allocation size. The global region contains class definitions, string constants, and other data internal to the VM. -Xglobal can be used to override the default size of 240 MB or the -client setting of 128 MB. Refer to Reducing Fast VM Memory Requirements for Workstations and Client-Side Applications for more information.

-Xmp

When used with the compacting garbage collector, this specifies the minimum percentage of heap space that the collector should try to free for new objects. Thus, it dictates when a full compaction must occur, rather than a sweep or minor compaction. Values from 0 to 100 may be specified in the form -Xmpnn, for example, -Xmp25. The default value is 25.

-Xms<size>

Specify the initial size of the memory allocation pool. This value must be greater than 1000. To multiply the value by 1000, append the letter k. To multiply the value by 1 million, append the letter m. See Dynamic Heap Management for information about the default value.

-Xmx<size>

Specify the maximum size of the memory allocation pool. This value must be greater than 1000. To multiply the value by 1000, append the letter k. To multiply the value by 1 million, append the letter m. See Dynamic Heap Management for information about the default value.

-XO

Do not generate stack trace information for exceptions.

-Xgc:compacting

Instructs the Fast VM to use the default compacting garbage collector. (See also Dynamic Heap Management.)

-Xgc:copying

Instructs the Fast VM to use the "copying" garbage collector.

-Xgc:full_explicit

Instructs the Fast VM to perform a full garbage collection when an explicit garbage collector call is made (system.gc()). By default, it may perform only a partial collection, depending on the current heap utilization.

-Xgc:ignore_explicit

Instructs the Fast VM to ignore explicit garbage collector calls.

-Xlock:private Always initializes monitor locks as private. (See also Fast VM Lock Initialization Options.)
-Xlock:shared Always initializes monitor locks as shared. (See also Fast VM Lock Initialization Options.)
 

 

Using the Fast VM with Java™ 2 Development Tools

Once the Fast VM is set up as your virtual machine, it is automatically used when you invoke any of the Java development tools (for example, javac, javadoc, javap, jar, appletviewer).

Tuning and Performance

This section contains information on tuning and performance for the Fast VM.

Memory Usage

The Fast VM has been tuned for large memory systems and, in addition, a number of trade-offs have been made that favor speed of execution over memory usage. As a result, the Fast VM uses more physical and virtual memory for the same application, often as much as 50 percent more. This can lead to excessive paging and degraded performance if the system is not tuned correctly or if there is insufficient physical memory on the system.

If you notice that your application runs more slowly with the Fast VM than the classic SDK JIT, you should do the following:

Note that you are better off with a smaller heap that results in more garbage collections than allowing your application to page fault too often due to a large heap size.

For more information on system tuning and resource limits, see the OpenVMS Performance Management manual.

Memory Layout

The Fast VM's memory layout has been restructured to grant an application access to an additional 512 MB of P0 space. This enhancement will allow an application to create more concurrent threads, memory for JNI libraries, and/or increase the Global memory space used by the Java VM.

Reducing Fast VM Memory Requirements for Workstations and Client-Side Applications

The Fast VM is optimized for large, long-running programs running on server systems. Many users would like to use the Fast VM on their workstations for client-side applications; however, some of these systems do not have the resources to start up the Fast VM with its default configuration. A -client switch addresses these needs.

The client configuration significantly reduces the Fast VM memory footprint.

The -client switch is a convenience switch, analogous to setting the following switches on a command line:

java -Xmx64m -Xglobal128m -Xgc:compacting

The individual switch settings that make up the -client switch can be overridden; for example:

java -client -Xmx256m

will initialize the Fast VM with a maximum heap size of 256 MB, with a maximum global region size of 128 MB, and with the compacting collector.

Dynamic Heap Management

Rather than use fixed values for the default settings for the memory allocation pool (Java heap), the Fast VM determines the defaults for the initial heap size (-Xms) and the maximum heap size (-Xmx) dynamically based on the environment in which it is executing as shown below:

max_memory = min (physical memory on machine, total memory available to the process)

default initial heap size = 10% of max_memory

default maximum heap size = 60% of max_memory

By setting heap size defaults automatically, the Fast VM adjusts the heap size based on the amount of memory that is available. This generally produces better results than specifying fixed -Xmx and -Xms values, especially for an application that is executed on different systems with varying amounts of memory. It is sometimes possible to obtain better results by specifying -Xmx and -Xms rather than letting the Fast VM pick the defaults. To determine what values to use you should use the -verbose:gc command line option to monitor your application's heap activity. If you notice that a large number of garbage collections are occurring, increase the heap size as much as possible without causing excessive page faults. Also see Memory Usage for additional information.

Garbage Collection of Class Data for Dynamically Generated Classes

Garbage collection in the Fast VM manages memory allocated in the heap. In other words, it reclaims memory associated with objects in the heap if it can be determined that these objects can not be referenced anymore. However, the Fast VM does not release the memory resources allocated while loading classes at any time during its run. This characteristic could result in memory being exhausted during the execution of long-running applications that dynamically create and execute classes (such as those that call into some class methods in the sun.reflect.* package). To remedy this situation, option -Xdynclassgc instructs the VM to manage memory resources allocated while loading dynamically generated classes, if they are no longer used.

Fast VM Garbage Collection Options

The Fast VM provides two garbage collectors, which suit different heap usage patterns and memory configurations. The default is a multi-threaded compacting garbage collector. This collector is a hybrid mark-sweep/mark-compact collector, which will avoid moving data when it is not necessary.

This collection scheme can have better performance characteristics and lower heap-size requirements for applications in which the heap contains a high percentage of long-lived data. This collector can also perform minor collections, rather than collecting the entire heap, when the percentage of live data is moderate. It can also perform sweeps that free space without moving any data at all. Thus, it also has performance advantages for applications with a moderate amount of long-lived data, but a high rate of short-lived object turnover. This collector is multi-threaded to provide better scaling on multiprocessor systems.

The second collector is a copying collector, which copies live data to an unused portion of the heap at collection time. This is best suited for applications with very small amounts of long-lived data relative to overall heap size. It may also have advantages on uniprocessor systems with small heap sizes, since the compacting collector's advantage of multithreading is lost there. To use this collector, specify the -Xgc:copying option on the command line.

Under the default compacting collector, explicit garbage collector calls (system.gc()) do not necessarily cause a full compaction. Depending on the current heap utilization and the free space goal specified by -Xmp, a partial compaction or a sweep may occur instead. However, for applications where it makes sense, the -Xgc:full_explicit option can be specified to force system.gc calls to perform full compactions. Generally, it is best to avoid calling system.gc() and to allow the Fast VM to decide when a collection is necessary. To specify that the Fast VM should ignore system.gc() calls entirely, use the -Xgc:ignore_explicit option. This may be useful if, for example, a third-party library containing unnecessary system.gc() calls is used.

Under the copying garbage collector, all explicit garbage collector calls cause full collections, unless -Xgc:ignore_explicit is used.

Fast VM Garbage Collection Profiling Options

This section describes the Fast VM Garbage Collection (GC) profiling options, which allow you to get heap dumps and allocation profiles at each garbage collection.

Option

Function

-Xverbosegc:alloc

Print an object allocation profile after each garbage collection

-Xverbosegc:file:<filename>

Print output of all -Xverbosegc options to specified file

-Xverbosegc:heap

Print pre- and post-garbage collection heap profiles

-Xverbosegc:heap_pre

Print pre-garbage collection heap profile

-Xverbosegc:heap_post

Print post-garbage collection heap profile

 

-Xverbosegc:file:<filename>

This option allows a file to be specified to which the output of all of the -Xverbosegc options given on the command line will be printed, instead of to the terminal.

-Xverbosegc:heap, -Xverbosegc:heap_pre, -Xverbosegc:heap_post

These options print heap profiles, sorted in descending order by bytes allocated of each object type in each size range, at each garbage collection. -Xverbosegc:heap prints a profile both before and after the collection, while heap_pre and heap_post allow you to specify only one or the other. For example, the output at the third garbage collection when running the SPECjbb2000 benchmark with the -verbose and -Xverbosegc:heap options and an initial/maximum heap size of 4 MB looks like:

--- Pre-GC Profile ---
   Bytes Objects     Sizeof Space%    Cum% Type
  537760    5729     64-512 28.25%  28.25% [C
  312160    5877       8-64 16.40%  44.65% [C
  279000   11625         24 14.66%  59.31% java/lang/String
  119624      13     4K-32K  6.28%  65.60% [B
   85152    2661         32  4.47%  70.07% spec/jbb/Item
   85088    2659         32  4.47%  74.54% spec/jbb/infra/Collections/nodeKeyRef
   65600       4     4K-32K  3.45%  77.99% [C
   60816     759     64-512  3.20%  81.18% [Ljava/lang/Object;
   55120     381     64-512  2.90%  84.08% [J
   49672      60   512-4096  2.61%  86.69% [B
   32784       1   32K-256K  1.72%  88.41% [Ljava/lang/Object;
   30408     153     64-512  1.60%  90.01% [I
   29216     332         88  1.53%  91.54% java/util/SimpleTimeZone
   26352    1098         24  1.38%  92.93% java/util/Hashtable$Entry
   12128     379         32  0.64%  93.56% spec/jbb/infra/Collections/longBTreeNode
    8080       1     4K-32K  0.42%  93.99% [S
    7384     219       8-64  0.39%  94.38% [I
    6912     144         48  0.36%  94.74% java/util/HashMap
    6328       2   512-4096  0.33%  95.07% [Ljava/util/Hashtable$Entry;
    6144     256         24  0.32%  95.40% java/util/HashMap$Entry
    5600     174       8-64  0.29%  95.69% [B
    4368     138       8-64  0.23%  95.92% [Ljava/util/HashMap$Entry;
    4016       1   512-4096  0.21%  96.13% [[B
    3952      82       8-64  0.21%  96.34% [Ljava/lang/Object;
    3800      95         40  0.20%  96.54% java/math/BigInteger
    3640       4   512-4096  0.19%  96.73% [Ljava/lang/Object;
    3232      12     64-512  0.17%  96.90% [B
    2608      14     64-512  0.14%  97.04% [Ljava/util/Hashtable$Entry;

...

<GC: Garbage Collection #3 with 4.00 MB Heap>
<GC:   Time since last collection     :       0.63 seconds>
<GC:   Time spent collecting          :       0.05 seconds>
<GC:   Data live before collection    :       1.96 MB>
<GC:   Data live after collection     :       1.22 MB>

<GC:   Data pinned during collection  :       0.27 MB>
--- Post-GC Profile ---
   Bytes Objects     Sizeof Space%    Cum% Type
  274120    2929     64-512 25.49%  25.49% [C
  154536    2908       8-64 14.37%  39.86% [C
  141144    5881         24 13.13%  52.99% java/lang/String
   85152    2661         32  7.92%  60.91% spec/jbb/Item
   65600       4     4K-32K  6.10%  67.01% [C
   60640     758     64-512  5.64%  72.65% [Ljava/lang/Object;
   55120     381     64-512  5.13%  77.78% [J
   32832       4     4K-32K  3.05%  80.83% [B
   32784       1   32K-256K  3.05%  83.88% [Ljava/lang/Object;
   29216     332         88  2.72%  86.59% java/util/SimpleTimeZone
   25872    1078         24  2.41%  89.00% java/util/Hashtable$Entry
   13136      16   512-4096  1.22%  90.22% [B
   12128     379         32  1.13%  91.35% spec/jbb/infra/Collections/longBTreeNode
    8080       1     4K-32K  0.75%  92.10% [S
    7296     216       8-64  0.68%  92.78% [I
    6328       2   512-4096  0.59%  93.37% [Ljava/util/Hashtable$Entry;
    5952     124         48  0.55%  93.92% java/util/HashMap
    5664     236         24  0.53%  94.45% java/util/HashMap$Entry
    3800      95         40  0.35%  94.80% java/math/BigInteger
    3744      33     64-512  0.35%  95.15% [I
    3640       4   512-4096  0.34%  95.49% [Ljava/lang/Object;
    3248     118       8-64  0.30%  95.79% [Ljava/util/HashMap$Entry;
    3232      12     64-512  0.30%  96.09% [B
    2544       1   512-4096  0.24%  96.33% [I
    2504      13     64-512  0.23%  96.56% [Ljava/util/Hashtable$Entry;
    2080     130         16  0.19%  96.75% java/util/jar/Attributes$Name
...

-Xverbosegc:alloc

This option tells the Fast VM to keep track of allocation points and to compile a list of how many objects/bytes of what type are allocated at each call site. An object allocation profile, sorted in descending order by bytes allocated, is printed after each garbage collection report. The object allocation profile is cumulative up until each garbage collection, and starts over again after each garbage collection. By default, the output goes to the terminal. The output tends to wrap because of fully specified method names in the method call information for every call site, so a wide terminal window is optimal for viewing these stack traces.

For example, the output of the second garbage collection report and object allocation profile when running the SPEC JVM98 benchmarks with the -Xverbosegc:alloc option and an initial/maximum heap size of 4 MB begins with:

<GC: Garbage Collection #2 with 4.00 MB Heap>
<GC:   Time since last collection     :       4.06 seconds>
<GC:   Time spent collecting          :       0.03 seconds>
<GC:   Data live before collection    :       1.96 MB>
<GC:   Data live after collection     :       0.77 MB>

<GC:   Data pinned during collection  :       0.23 MB>

Object Allocation Profile #2:
 objects      bytes alloc% class
---------------------------------
       1     160016   8.8% [I
                           46: spec/benchmarks/_205_raytrace
/Canvas.<init>(II) 61: spec/benchmarks/_205_raytrace
/RayTracer.run([Ljava/lang/String;) 2: spec/benchmarks/_205_raytrace
/RayTracer.inst_main([Ljava/lang/String;) 65: spec/benchmarks/_227_mtrt
/Main.runBenchmark([Ljava/lang/String;) 1: spec/benchmarks/_227_mtrt
/Main.harnessMain([Ljava/lang/String;) 84: spec/harness/ProgramRunner.runOnce(Ljava
/lang/Object;IJILjava/util/Properties;) 481: spec/harness/ProgramRunner.runBenchmark2() 43: spec/harness/ProgramRunner.runBenchmark() 8: spec/harness/ProgramRunner.run() 221: spec/harness/RunProgram.run(Ljava/lang/
String;ZLjava/util/Properties;Lspc/harness/BenchmarkDone;) 16: SpecApplication.runBenchmark(Ljava/lang/String;Z) 609: SpecApplication.main([Ljava/lang/String;) 1695 138064 7.6% [C 56: java/lang/String.<init>([CII) 7: java/lang/String.copyValueOf([CII) 202: java/io/DataInputStream.readLine() 304: spec/benchmarks/_205_raytrace/
/Scene.ReadPoly(Ljava/io/DataInputStream;I) 186: spec/benchmarks/_205_raytrace
/Scene.LoadSceneOrig(Ljava/lang/String;) 8: spec/benchmarks/_205_raytrace
/Scene.LoadScene(Ljava/lang/String;) 6: spec/benchmarks/_205_raytrace
/Scene.<init>(Ljava/lang/String;) 11: spec/benchmarks/_205_raytrace/Runner.run() 1719 137904 7.6% [C 56: java/lang/String.<init>([CII) 7: java/lang/String.copyValueOf([CII) 202: java/io/DataInputStream.readLine() 202: spec/benchmarks/_205_raytrace
/Scene.ReadPoly(Ljava/io/DataInputStream;I) 186: spec/benchmarks/_205_raytrace
/Scene.LoadSceneOrig(Ljava/lang/String;) 8: spec/benchmarks/_205_raytrace
/Scene.LoadScene(Ljava/lang/String;) 6: spec/benchmarks/_205_raytrace
/Scene.<init>(Ljava/lang/String;) 11: spec/benchmarks/_205_raytrace/Runner.run() 3438 137520 7.5% java/lang/FloatingDecimal
...

In the second entry of the above object allocation profile, 1695 objects totaling 138064 bytes and of type [C (array of char) were allocated with the call chain shown, and account for 7.6 percentof the total bytes allocated from the first up until the second garbage collection.

For primitive types, the type names are defined as follows:

    V - void
B - byte
Z - boolean
C - char
S - short
I - int
F - float
J - long
D - double

For array types, the names shown are prefixed with [. For object types, the names shown are prefixed with L.

Note: The overhead of allocation profiling will dramatically decrease your application performance.

Fast VM Lock Initialization Options

In the Fast VM, Java monitors, which are locks used for code synchronization, are implemented using an optimized sequence of monitor states. They are initialized as "private" (to a thread), which allows extremely lightweight locking. If threads share a monitor, it is promoted to a "shared" state. If the Fast VM determines that promotion to the shared state is extremely common, it may instead begin initializing monitors in that state, to avoid the cost of promotion.

In some rare instances, application performance might benefit from forcing the Fast VM to always initialize monitors as private or shared, regardless of how often promotion does or does not occur. The -Xlock option allows you to specify the initial lock state, but should only be used if you are very familiar with your application's locking behavior.

-Xlock:private — Always initialize monitor locks as private.
-Xlock:shared — Always initialize monitor locks as shared.

Creating a VM in C/C++ Programs Using the Invocation API

This release of the Fast VM supports the ability to create and invoke the Fast VM in C/C++ programs using the Invocation API. The Invocation API is an integral part of the Java Native Interface (JNI) that allows you to initialize virtual machine arguments, create and load a virtual machine into your application, and then unload or destroy the virtual machine. For additional information about the Invocation API and how to use it, refer to the Sun JNI specification.

In order to take advantage of the Invocation API functionality, your C/C++ program (new and existing programs) must first create the virtual machine so that the Java code can be executed. Once the virtual machine is embedded into the program, the program can then load Java classes and execute Java methods.

Assume that you have a C++ program called invokejvm.cxx that creates a virtual machine and then calls a Java method. The following example shows how to compile and link a C++ program that invokes the Fast VM:

  1. Make sure the Fast VM is set up as your virtual machine.


  2. Create an options file that tells the linker to use the JAVA$JVM_SHR shareable image. Using SDK v 1.4.1 as an example, you could create EXAMPLE.OPT containing the line:
  3. JAVA$JVM_SHR/SHAREABLE
  4. Then compile and link:
    $ CXX INVOKEJVM.CXX /INCLUDE=SYS$COMMON:[JAVA$141.INCLUDE...] -
      /NAMES=AS_IS/FLOAT=IEEE
    $ LINK INVOKEJVM, EXAMPLE/OPTIONS
    

The /NAME=AS_IS qualifier is required to preserve the original case of external name strings. If your C/C++ code shares floating-point data with the RTE, the /FLOAT=IEEE qualifier is required because the RTE uses IEEE format floating-point, while C/C++ uses G-floating by default.

After you link the example, the program will use either the classic virtual machine or the Fast VM, depending on your Java environment setup, because it was linked with just JAVA$JVM_SHR, not the specific file that the logical name translates to.

Back to top
Using the Plug-In

The Java Plug-in enables users to run Java applets and JavaBeans components on web pages using the RTE as an alternative to using the default Virtual Machine for Java 2 that comes with the web browser. It is based on the Java Plug-in provided by Sun Microsystems and contains similar functionality.

For additional information on topics such as Java Plug-in security, using Signed Applets, JNI and the Java Plug-in, using the Java Plug-in in Intranet Environments, and how Proxy Configuration works in the Java Plug-in, please see the Sun Microsystems Java Plug-in Product web site.

Note: Mozilla® 1.1 is the minimum version of Mozilla that supports SDK v 1.4.x.

Note: For simplicity, this document assumes you installed the SDK using the default location and therefore references SYS$COMMON:[JAVA$14x] throughout the text. However, if you specified a destination and installed the kit in that alternate location, substitute that location for the default while reading this document.

Installing and Running Mozilla and the Plug-In

To install Mozilla:

  1. Download Mozilla.
  2. Refer to the OpenVMS Systems Mozilla Installation Guide and Release Notes to install Mozilla on your system.

To run Mozilla:

$ @sys$common:[mozilla]mozilla

Note: We strongly recommend that you run Mozilla as an interactive job as indicated above.

If you spawn it off as a subprocess:

$ spawn/nowait @sys$common:[mozilla]mozilla

you will likely exhaust some resources if you attempt to use the plug-ins for anything non-trivial.

To enable the RTE within your browser:

  1. Set preference:
    Edit->Preferences
    Click on Advanced.
    Check button labeled Enable Java.
  2. Exit Mozilla.

  3. When both SDK v 1.4.x and Mozilla have been installed in the standard areas, perform a one-time file copy to install the Plug-in:
    $ copy /prot=W:RE -
    SYS$COMMON:[JAVA$14x.JRE.PLUGIN.ARCH.NS610]LIBJAVAPLUGIN_OJI.SO -
    SYS$COMMON:[MOZILLA.PLUGINS]
    where x is the specific version number of the release you are using, and ARCH is ALPHA or I64. Thereafter, you can set up for Java operation:
    $ @SYS$COMMON:[JAVA$14x.COM]JAVA$14x_SETUP.COM
    where x is the specific version number of the release you are using.


  4. Then run Mozilla:
    $ @sys$common:[mozilla]mozilla
    Mozilla will notice that new plug-ins are available and will then initialize those plug-ins for the current invocation.

To verify that Mozilla has found the plug-ins refer to:

Help->About Plug-ins

Mozilla will display the plug-ins it has initialized.

Placing Plug-ins

As of Mozilla 1.1 and Secure Web Browser (SWB) 1.0, you can choose where to place plug-ins.

For "system wide" use, the location would be (as before) in the Mozilla/SWB installation tree:

SYS$COMMON:[MOZILLA.PLUGINS]
SYS$COMMON:[CSWB.PLUGINS]

For example, for SWB, use the following command to place the plug-in in the "system-wide" location:

$ copy /PROT=W:RE -
SYS$COMMON:[JAVA$14x.JRE.PLUGIN.ARCH.NS610]LIBJAVAPLUGIN_OJI.SO -
SYS$COMMON:[CSWB.PLUGINS]

where x is the specific version number of the release you are using and ARCH is ALPHA or I64.

You can also set up "private" plug-ins by creating a [.PLUGINS] directory in your _MOZILLA directory (which resides in SYS$LOGIN). For example:

USERS:[FLINTSTONE._MOZILLA.PLUGINS]

The Plug-in Control Panel

A Plug-in Control Panel lets you change Plug-in options such as proxies and enabling of the Java console window. It also allows you to switch the RTE version you want to run with your Plug-in. To run the Control Panel, enter the following command:

$ ControlPanel

Or you can use the Mozilla browser to visit the Control Panel applet page that was installed as 

SYS$COMMON:[JAVA$14x.JRE]ControlPanel.html

For example:

@sys$common:[mozilla]mozilla -
file:///SYS$COMMON:[JAVA$14x.JRE]ControlPanel.html

where x is the specific version number of the release you are using. Some of the Control Panel features are discussed below. Refer to Sun's Using the Java Plug-in Control Panel to Set Plug-in Behavior/Options web page for information about additional features and uses of the Java Plug-in Control Panel.

Viewing Tracing Information

You can view a moderate amount of Java Plug-in tracing information in Mozilla's Java Console by setting the JAVA_PLUGIN_TRACE environment variable:

  1. Type the following before starting Mozilla:
    $ DEFINE JAVA_PLUGIN_TRACE true
  2. Open the Java Console (Tools->Web Development->Java Console).

Displaying Java Error Messages

To see Java error messages:

  1. Use the Plug-in Control Panel to enable the console window.
  2. Exit Mozilla and then restart it.

With the console window enabled, when you next visit a Plug-in enabled page, a separate window will come up to display error messages.

Back to top
Font Support

The SDK release includes the following font support.

Role of the font.properties File

Starting with J2SDK v 1.2.1, Java applications require a font property file to properly display the application's AWT windowing and Java2D components. This file contains mappings of Java logical font names to physical fonts on the X server and is installed by this kit in SYS$COMMON:[JAVA$14x.JRE.LIB]FONT.PROPERTIES, where x is the specific version number of the release you are using. It identifies fonts that should be available on your X server. This version is different from previous versions of the Java Development Kit (JDK) 1.1.n, where a font property file was not required. Instead of using Java default fonts, which were resolved at run-time by the X server to physical fonts on the display side, the font.properties file provides a mapping of the Java logical font names to fonts on the system. This allows for greater consistency across Java applications using the same J2SDK. Therefore, you might notice some differences in your window displays because of the fonts now being used. You might also see a noticeable difference in the size of the text displayed when using the J2SDK compared with using JDK 1.1.n; text will now be displayed larger. This is because JDK 1.1.n as implemented by Sun for Solaris incorrectly implements font point sizes causing text to appear smaller on the screen. This was fixed in J2SDK v 1.2.1 and the correct point sizes for fonts are now used. If your GUI display does not appear as expected, you may need to make some adjustments in your application for a component's size and placement.

If you prefer to use fonts other than those that have been predefined by the property file for your use, copy the file installed by this kit from [.JRE.LIB]FONT.PROPERTIES to your SYS$LOGIN directory and modify it. When you run a Java application, it will use your local font property file instead of the one installed by this kit.

Note: For simplicity, this document assumes you installed the SDK using the default location and therefore references SYS$COMMON:[JAVA$14x] throughout the text. However, if you specified a destination and installed the kit in that alternate location, substitute that location for the default while reading this document.

Multiple font.properties Files Provided

It is difficult to supply a font.properties file that is ideal for use in all environments — to enable the use of many fonts in environments that have them, yet work properly in font-poor environments.

As a result, this kit contains three font.properties files:

  • font.properties

    This default font.properties file is optimized for use if you plan on displaying your application only to OpenVMS and Tru64 UNIX workstations.

  • font_properties.excursion

    This alternate font.properties file is optimized for use if you plan on displaying your application only to PCs running the DIGITAL eXcursion™ window manager. It takes advantage of the rich font environment.

  • font_properties.rotation

    This alternate font.properties file has been modified for your use if your application uses Java2D features such as displaying rotated text. This file uses TrueType fonts supplied by Sun that ship with the Java 2 SDK. Not all of the fonts in this property file support the display of rotated text. Only the "SansSerif" and "Monospaced" font families were changed to use Sun's fonts.

    If your application displays text as rotated, you will need to follow a few simple steps in order to successfully use this Java2D feature. In your program, for all of the occurrences of text that you wish to display as rotated, you will need to call the setFont() method to change the font name for the text to "SansSerif" or to "Monospaced". Additionally, you will need to use this font property file on a user local or system-wide basis.

All of these files reside in [.JRE.LIB], and the one actually named font.properties is the one that will be used. This file is a system-wide file and is used for the display of all Java programs that are run on that system. The SDK supports local customizations of the font property file which can take affect on a user or system-wide basis. When the RTE needs to find a font.properties file, it starts its search in SYS$LOGIN. A local version of the font.properties file takes precedence over a system-wide version. Therefore, you can make one of these three files your user local font.properties by copying the font property file of your choice to a file named font.properties in SYS$LOGIN.

If you prefer to use fonts other than those that have been predefined by the font properties file for your use, copy the file installed by this kit from [.JRE.LIB]FONT.PROPERTIES to your SYS$LOGIN directory and modify it. When you run a Java application, it will use your local font property file instead of the one installed by this kit. The following example makes the eXcursion version of the file the one that is used, on a user-local basis only. Alternatively, you could have specified the font_properties.rotation file that supports text rotation.

$ COPY SYS$COMMON:[JAVA$14x.JRE.LIB]font_properties.excursion -
       SYS$LOGIN:font.properties

where x is the specific version number of the release you are using. Alternatively, if you want to use the font_properties.excursion file as a system-wide file for use by all users on the system (thus overriding the system-wide default font.properties file), perform the following steps:

$ COPY SYS$COMMON:[JAVA$14x.JRE.LIB]font.properties - 
SYS$COMMON:[JAVA$14x.JRE.LIB]font_properties.orig
$ COPY SYS$COMMON:[JAVA$14x.JRE.LIB]font_properties.excursion -
       SYS$COMMON:[JAVA$14x.JRE.LIB]font.properties

where x is the specific version number of the release you are using. If later you wish to revert to the original file that shipped with the SDK kit, you would copy font_properties.orig to font.properties.

Displaying Chinese Characters

This kit provides the SYS$COMMON:[JAVA$14x.JRE.LIB]FONT_PROPERTIES.ZH_DECHANZI font property file, which supports displaying Simplified Chinese characters when the user sets his locale to "ZH_CN_DECHANZI". DEC Hanzi supports the GB2312 code set on OpenVMS Alpha. Due to existing limitations, only AWT GUI components (and not Swing components) can be displayed properly for this encoding. OpenVMS Alpha V7.2-2, OpenVMS/Hanzi V7.2-2, DECwindows Motif V1.2-6 for OpenVMS, and DECwindows Motif/Hanzi V1.2-6 for OpenVMS (or later versions of any of these) are required.

Font Problems?

Font Warnings: When using Japanese Motif, you should use the following font specification sizes 8, 10, 12, 14, 18, or 24. When other sizes are specified by an application, Japanese text is not displayed. For Japanese Motif, Java font specifications for application and applets are described in the file SYS$COMMON:[JAVA$14x.JRE.LIB]FONT_PROPERTIES.JA, where x is the specific version number of the release you are using. If you encounter one of the following warnings, you are probably referencing a font in your font.properties file that is not available on your system. Check your font path by issuing the OpenVMS command: $ mcr decw$utils:xset.exe -q. If your font path setting is not what you expect, you might need to change the search order. Also, make sure that the font property file references fonts that are installed on your system; you may be attempting to use a font that is not available.

Font specified in font.properties not found [-*-helvetica-bold-r-normal...]"

If you are having problems with fonts when you display remotely to a PC using eXcursion™, you might need to upgrade to a newer version of the eXcursion software and install additional fonts. Also, make sure that the font property file references fonts that are installed on your PC.

Japanese Text Fonts: When using Japanese Motif, you should use the following font specification sizes 8, 10, 12, 14, 18, or 24. When other sizes are specified by an application, Japanese text is not displayed. For Japanese Motif, Java font specifications for application and applets are described in the file SYS$COMMON:[JAVA$14x.JRE.LIB]FONT_PROPERTIES.JA, where x is the specific version number of the release you are using.

Choosing font_properties.xx by Locale: The graphic package AWT should pick font_properties.xx according to current locale, where xx means a country code such as ja and ko. For example, font_properties.ja is used in Japanese locale and font_properties.ko is used in Korean locale, instead of font.properties.

This automatic selection based on locale does not work correctly; as a workaround, if the user copies the desired font_properties.xx into his SYS$LOGIN directory as font.properties, the desired font properties file will be accessed by default. For example,

$ COPY SYS$COMMON:[JAVA$14x.JRE.LIB]FONT_PROPERTIES.JA -
SYS$LOGIN:FONT.PROPERTIES

where x is the specific version number of the release you are using.

Back to top
Using the Java Print Service API

In order to make the Java Print Service API (javax.print) work correctly on OpenVMS, it is necessary to define the following logicals. These logicals intercept the attempted issuing of hard-coded UNIX-style lpr commands with the corresponding OpenVMS PRINT commands, and replace the UNIX-style file specification with the OpenVMS-style file specification needed by the PRINT command.

$ define JAVA$EXEC_MAPPING_01 -
           "/bin/sh=/sys$common/java$142/com/java$$sh.com"


! intercept sh command

$ define JAVA$EXEC_MAPPING_02 -
           "/usr/bin/lpr=/sys$common/java$142/com/java$$lpr.com"


! intercept lpr command

$ define JAVA$EXEC_MAPPING_03 -
           "/usr/bin/lp=/sys$common/java$142/com/java$$lpr.com"


! intercept lp command

$ define JAVA$DEFAULT_PRINTER_QUEUE POD303

! specify favorite print
  queue

Back to top
Debugging Tools

You can define the following logical names to assist in debugging.

JAVA$PRINT_COMMAND_ARGS

$ define JAVA$PRINT_COMMAND_ARGS true

When defined, this prints out the parsed argument list before the RTE sees it and tabulates the argument list before the RTE can add default parameters like "-Djava.class.path=."

For example:

$ type x.x
-Xms64m

$ java "-V" x.x decus wait_time

will produce as output (using SDK v 1.4.1 as an example):

0: sys$common:[JAVA$141.bin]java$java.exe
1: -Xms64m
2: decus
3: wait_time

_JAVA_LAUNCHER_DEBUG

$ define _JAVA_LAUNCHER_DEBUG 1

This will show the arguments in effect at the time the Java Virtual Machine starts up.

$ java -mx32m TestArgs “< = 1” 2 3
  ----_JAVA_LAUNCHER_DEBUG----
  JRE path is /sys$common/java$142/jre
  jvm.cfg[0] = ->-classic<-
  1 micro seconds to parse jvm.cfg
  Does ‘java$jvm_shr’ exist ... yes.
  JVM path is java$jvm_shr
  JavaVM args:
        version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 2
        option[ 0] = ‘-Djava.class.path=.’

        option[ 1] = ‘-Xmx32m’
  1 micro seconds to InitializeJVM
  Main-Class is ‘TestArgs’
  Apps’ argc is 3
        argv[ 0] = ‘< = 1’
        argv[ 1] = ‘2’

        argv[ 2] = ‘3’
  1 micro seconds to load main class
  ----_JAVA_LAUNCHER_DEBUG----
  $

JAVA$EXEC_TRACE

$ define/job JAVA$EXEC_TRACE true

You can use the logical name JAVA$EXEC_TRACE to help debug Runtime.exec() calls on OpenVMS. When this logical is defined, a printout displays the C Run-Time Library exec variant and its list of arguments.

JAVA$ENABLE_SIGQUIT_CTRLC

$ define JAVA$ENABLE_SIGQUIT_CTRLC true

This replaces the ^] feature in UNIX.

When defined, a CRTL-C handler will be established that will raise the SIGQUIT signal. Then, if you type ^C, the RTE dumps out all the Java thread information.

This logical will only work for terminal devices, when the RTE is running interactively from a terminal process. See JAVA$ENABLE_SIGQUIT_MAILBOX for information on how to communicate with batch jobs or detached jobs.

JAVA$ENABLE_SIGQUIT_MAILBOX

$ define JAVA$ENABLE_SIGQUIT_MAILBOX true

Use this logical to force a Java application to dump threads, if no terminal is involved, e.g., a batch job or a detached job. Use it to dump out where the subprocess is stuck. This mimics UNIX sending a SIGQUIT to a Java process. When this logical is defined, the RTE creates a temporary mailbox you can ping from another process, allowing you to ping stuck batch jobs.

To use this, perform the following steps:

Before starting the Java application, define the following logical:

$ define JAVA$ENABLE_SIGQUIT_MAILBOX true

This causes the RTE to create a logical with a mailbox name. After starting your Java application, scan the job logicals tables to determine the correct mailbox. Run the following command from another terminal:

$ pipe show log/table=* *signal* | search sys$input: signal

Sample output:

"JAVA$SIGNAL_MAILBOX_20200234" = "MBA90:"

For the process pid 20200234 you have a mailbox MBA90:.

Issue the following command, substituting your mailbox name for MBA90:

$ copy tt: MBA90:

You will not see any output, but whenever you press RETURN, the subprocess will print a thread dump.

When done, type ^Y to exit the COPY command.

JAVA$FSYNC_INTERVAL

RMS buffers are not usually flushed to disk until the buffer is full or the program exits. If you want to view the contents of the file before the buffer is full (e.g., monitoring a logfile for output), the JAVA$FSYNC_INTERVAL logical allows you to define an interval after which all pending output is flushed to the disk with the command:

$ define/job JAVA$FSYNC_INTERVAL <number_of_seconds>

For example,

$ define/job JAVA$FSYNC_INTERVAL 60 ! flush any pending output to disk every 60 seconds.

Note: Defining the logical to a very low value could cause performance degradation.

JAVA$SHOW_FILENAME_MAPPING

Use this logical to see the individual filename mappings as they occur. In the example below, the jar file contains a class file that has two dots in its filename. With JAVA$FILENAME_CONTROLS defined to -1, multiple dots in the filename are turned into underscores, but the last dot is retained. To observe this as it happens, define JAVA$SHOW_FILENAME_MAPPING. This will generate a large amount of output, so you may choose to filter it out using pipe , as shown.

$ jar tvf tmp.jar
0 Fri Jan 03 13:12:38 GMT-05:00 2003 META-INF/
68 Fri Jan 03 13:12:38 GMT-05:00 2003 META-INF/MANIFEST.MF
10 Fri Jan 03 13:12:14 GMT-05:00 2003 file.1.class

$ show log java$filename_controls
"JAVA$FILENAME_CONTROLS" = "-1" (LNM$JOB_816DA700)
$ show log java$show_filename_mapping
"JAVA$SHOW_FILENAME_MAPPING" = "1" (LNM$PROCESS_TABLE)
$ pipe jar xvf tmp.jar | search sys$input file.1
open_Jacket: Mapped: file.1.class To: file_1.class
extracted: file.1.class

Back to top
Troubleshooting

The following scenarios suggest resolutions to problems you might encounter on OpenVMS systems when using the RTE.

One-to-One Relationship Between Class Names and File Names

Problem:

You wrote a Java program in a file called SERTEST.JAVA. The public class definition starts off with:

    public class SerTest {
    ...

You've tried to compile it with the following:

   $ javac SERTEST.JAVA

and also with:

   $ javac sertest.java

In both cases the compilation fails with the error message:

    sertest.java:7:
    Public class SerTest must be defined in a
        file called "SerTest.java".
    public class SerTest {
                 ^
    1 error

What's wrong?

The Java runtime environment insists in a one-to-one relationship between class names and file names. You must express the file name in the same case-sensitive manner as your public class declaration, namely SerTest.java.

So, in this example, you need to type the command as:

   $ javac "SerTest.java"

If the file name is not in quotation marks, DCL automatically uppercases the string. So by the time javac sees it, the file name is SERTEST.JAVA, which does not match the class name.

Java Source Files on OpenVMS Systems Must Be in Stream_LF Record Format

Problem:

You copied some Java source files from another computer and/or have created some new .java files from scratch. Some files compile just fine on your OpenVMS system. But if an error occurs, the error message tells you what the error is but the indicator ^, showing where the error occurs on the line, does not point to anything.

What's wrong?

Java source files on OpenVMS systems must be in Stream_LF record format, although other record formats will work if the compilation is error-free. However, if an error occurs, the program cannot show you where it is on the line. To do this, the file must be in Stream_LF record format. Enter the command:

$ DIR/FULL mysource.java

Then note the line that starts with the string:

Record format:

If the Record Format is not shown as Stream_LF, you must convert it to Stream_LF. Text files can be converted to Stream_LF format with the following command:

$ CONVERT/FDL=STREAM_LF.FDL input_file.JAVA output_file.JAVA

An example of a valid STREAM_LF.FDL is shipped on the kit and can be found in:

SYS$COMMON:[JAVA$14x.COM]STREAM_LF.FDL

where x is the specific version number of the release you are using.

Problem:

You copied a .ZIP file from another computer and added a reference to this .ZIP file to your CLASSPATH. You still get error messages indicating that the system is not seeing the classes defined in your new .ZIP file.

What's wrong?

Make sure that the new .ZIP file is in Stream_LF record format. Enter the following command:

$ DIR/FULL MY.ZIP

Note the line that starts with the string:

   Record format:

If the Record Format is not shown as Stream_LF, you must convert it to Stream_LF. Binary files like .ZIP files can be converted to Stream_LF format with the following command:

   $ SET FILE MY.ZIP /ATTR=(RFM:STMLF,RAT:CR)

For more details, see Stream_LF File Format Required.

ECOs Must Be Installed

Problem:

You get error messages like the following:

%IMGACT-F-SYMVECMIS, shareable image's symbol vector table mismatch
-IMGACT-F-FIXUPERR, error when JAVA$JAVA_SHR referenced DECC$SHR

What's wrong?

The SDK for OpenVMS has been linked against a specific set of OpenVMS shareable images that are assumed to be on the user's system at runtime. These images contain enhanced functionality required by the RTE. This specific set of images is packaged into one or more ECOs (Engineering Change Orders). For a list of ECOs required for your version of OpenVMS, see the patch installation page on our Web site for SDK v 1.4.1, or the Release Notes for SDK v 1.4.2, depending on the SDK version that you are running. You must download and install these ECOs for the RTE to operate correctly.

Problem Displaying to a VAXstation

Problem

Your Java application correctly displays its output to an AlphaStation; however, you may see the following message when trying to redirect the display to a VAXstation:

     X error event received from server:  BadValue (integer parameter out of
                                                     range for operation)
     Major opcode of failed request:  61 (X_ClearArea)
     Value in failed request:  0xffff****
     Serial number of failed request:  ###

     Current serial number in output stream:  ###
     %XLIB-E-ERROREVENT, error event received from server
     %TRACE-E-TRACEBACK, symbolic stack dump follows

     (* indicates a variance in the occurrence of the width & height)
       This is a problem with (width, height).

What's wrong?

The OpenVMS server implements these parameters (width, height) as a signed word as opposed to CARD16 (unsigned word) as specified by the X Windows System Protocol. Hence, anything over 32767, (hex 7fff) is unacceptable to an OpenVMS server.

To fix this, add the following line to file SYS$MANAGER:DECW$PRIVATE_SERVER_SETUP.COM:

$ DEFINE/TABLE=DECW$SERVER0_TABLE DECW$CARD16_VALIDATE TRUE

for the DECW$PRIVATE_SERVER_SETUP.COM controlling your VAXstation and restart DECwindows.

Classpath Disrupted by File with No Name or Extension

Problem

Classpath is disrupted, resulting in a NoClassDefFoundError error.

What's wrong?

The presence of a file named .; on the classpath (a file with no name or extension) will result in a failure to find the class file specified on the command line. Note the following example:

$ java helloworld
Hello world.


$ create .
EXIT
$ java helloworld
Exception in thread main java.lang.NoClassDefFoundError: helloworld

Java.net Methods Using Certain OpenVMS Socket Operations Can Fail with Permission Denied

Problem

Some java.net methods may fail with the following error:

SocketException: "permission denied"

What's wrong?

This can occur because some of these methods use OpenVMS socket operations that require "OPER" (or higher) privilege. See A-1 in the TCP/IP Services for OpenVMS Sockets API and System Services Programming manual for more information about OpenVMS sockets.

Some Images Do Not Exit on ^Y When Another Image Is Started

Problem

A few Java utilities (javap, javah, and verify), do not exit cleanly if they are aborted with a ^Y.

What's wrong?

When you then type another command, or even $ EXIT, you might find that you have to do a second ^Y and another $ EXIT in order to stop all the threads that are running on your behalf.

If the application is deadlocked, holding a resource required by one of the exit handler's routines, the application will continue to hang, even after typing ^Y and EXIT. In these cases, type a second ^Y and STOP to terminate the application without running exit handlers. This behavior is not unique to Java applications but is characteristic of DECthreads operating in a multithreaded environment. See the Guide to the POSIX Threads Library (Appendix B) for a full discussion of this issue.

Changing the System Time Zone

Problem

After changing the system time zone, the Java application does not display the new time zone.

What's wrong?

If you change time zones, for example, Eastern time to Pacific time (not just the daylight saving time to standard time), while a Java application is running, expect that the Java application will continue to display/use the previously set time zone as the correct time zone (Default TimeZone, as described on Sun's site). Time will be adjusted as if the system were moved to the new time zone; however, it will display the previously set time zone. The RTE will automatically account for the time-zone shift (for example, from daylight saving to standard time), independent of the system time.

As always, consult the OpenVMS System Manager's Manual, Chapter 6, Setting System Time for information on setting the system time.

Benchmarking with VolanoMark™

Problem

VolanoMark exhausts all buffer I/O resources and hangs the system.

What's wrong?

The VolanoMark benchmark requires a large buffered I/O byte count quota. If you plan to try out the VolanoMark benchmark, increase the byte count quota to approximately 3 million.

Exhausting Event-Flag Numbers When Using Socket

Problem

If you start to exhaust the number of available Event Flag Numbers (EFNs), you will see an error message like the following:

Thu May 28 17:44:22 EDT 1998 Error starting connection.

 java.net.SocketException: insufficient event flags
          at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:387)
          at java.net.ServerSocket.implAccept(ServerSocket.java:206)
  ...

What's wrong?

On OpenVMS systems running TCP/IP Services lower than version 5.0, the operation of sockets is controlled by Event Flag Numbers (EFNs). The more sockets you operate simultaneously, the more EFNs you consume. There are only 32 EFNs available for your use.

Back to top
Documentation

The SDK v 1.4.x documentation tree begins at the following location on the system where the SDK is installed:

SYS$COMMON:[JAVA$14x.DOCS]INDEX.HTML

where x is the specific version number of the release you are using. The installed documentation is in HTML format and includes the release notes file and this user guide file, as well as the aforementioned index.html file.

Note: For simplicity, this document assumes you installed the SDK using the default location and therefore references SYS$COMMON:[JAVA$14x] throughout the text. However, if you specified a destination and installed the kit in that alternate location, substitute that location for the default while reading this document.

For core API documentation, refer to the following sources:

Also, you can browse the Software Documentation page on our web site. Optimizing Java Technology Software Performance on OpenVMS provides tips on improving Java performance on OpenVMS systems.

For more information, refer to the Release Notes for the J2SDK v 1.4.1 or the Release Notes for the J2SDK v 1.4.2 software from Sun Microsystems, and the Release Notes for this SDK.

If you are new to the Java programming language, you can browse or download Sun's Java Tutorial.

Problem Reporting

To report problems, refer to our Software Support web page.

© 2005 Hewlett-Packard Development Company, L.P.

Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license.

The information contained herein is subject to change without notice. The only warranties for HP products and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein.

Microsoft, Windows, and Windows NT are U.S. registered trademarks of Microsoft Corporation.

Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.

Printed in the US