Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
»  Contact HP
Java Technology Software
HP.com home

User Guide

J2SE™ Development Kit (JDK) 6.0x
for the OpenVMS Operating System

for the Java™ Platform

Content starts here

Contents

Back to top
Introduction

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

Note: JDK 6.x is designed to run only on Integrity servers running the OpenVMS I64 Operating System.

For information on the specific version of the JDK, 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 J2SE from Sun that the JDK implements
  • The specific Solaris Reference Release on which the JDK is based
  • Sun's Java Compatibility Kit test suite, whose tests the JDK passes
  • Prerequisites, including supported operating system versions

The JDK contains the following virtual machine:

  • 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.

Before JDK 6.x, the Java heap size was limited to 2GB. This limit has been lifted in JDK 6.x. The application can use a large heap with a maximum of 32GB.

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 JDK.

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

4096

Wsquo

8192

Wsextent and Wsmax

32768

Pgflquo

3145728*

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 192 MB when using the JRE. When you increase the Pgflquo parameter, you should always increase the system's page file size to accommodate the new Pgflquo parameter, if needed.

Setting Up the Java Environment

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

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

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

Note: For simplicity, this document assumes you installed the JDK using the default location and therefore references SYS$COMMON:[JAVA$6x] 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.

Note: The JDK 6.x must be installed on an ODS-5 formatted disk. See 'Installing the kit' in the Release Notes for details on how to control where the kit is installed.

JAVA$6x_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 JDK's shareable images

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

  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/SeaMonkey

  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 JDK 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$6x.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$6x/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$6x_SETUP.COM. These command procedures are independent of JAVA$6x_SETUP.COM.

The first command procedure can be found in:

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

When you execute the following procedure:

$ @SYS$COMMON:[JAVA$6x.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) that is written to the current directory, and 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$6x.COM]JAVA$CHECK_ENVIRONMENT.COM

When you execute the following procedure:

$ @SYS$COMMON:[JAVA$6x.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$6x.COM]JAVA$CHECK_ENVIRONMENT.COM

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

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

  3. Set up the Java environment, select VM:

    $ @SYS$COMMON:[JAVA$6x.COM]JAVA$6x_SETUP.COM {HOTSPOT}

  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$6x_SETUP.COM.

Switching Versions

You can have multiple JDK 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 JDK using the default location and therefore references SYS$COMMON:[JAVA$6x] 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 JDK versions in separate processes, you must first run a command procedure to set up the Java environment definitions for the version of the JDK you want to use in the given process. The command procedures to perform the Java environment setup are version-specific, and are as follows:

JDK Version

Command Procedure

JDK 6.0 SYS$COMMON:[JAVA$60.COM]JAVA$60_SETUP.COM
JDK 1.5.0 SYS$COMMON:[JAVA$150.COM]JAVA$150_SETUP.COM

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 JDK 6.0, first run the following command file in your process:

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

In the Same Process

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

JDK Version

Command Procedure

JDK 6.0 SYS$COMMON:[JAVA$6x.COM]JAVA$60_CANCEL_SETUP.COM or JAVA$CANCEL_CURRENT
JDK 1.5.0 SYS$COMMON:[JAVA$15x.COM]JAVA$150_CANCEL_SETUP.COM or JAVA$CANCEL_CURRENT

SDK v 1.4.2

SYS$COMMON:[JAVA$15x.COM]JAVA$142_CANCEL_SETUP.COM or JAVA$CANCEL_CURRENT

SDK v 1.4.1 SYS$COMMON:[JAVA$15x.COM]JAVA$141_CANCEL_SETUP.COM

SDK v 1.4.0

SYS$COMMON:[JAVA$15x.COM]JAVA$140_CANCEL_SETUP.COM

SDK v 1.3.1

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

SDK v 1.3.0

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

SDK v 1.2.2

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

SDK v 1.1.8 SYS$COMMON:[JAVA$15x.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$142.COM] does not contain JAVA$150_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 JDK 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. 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 JRE 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 JDK 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 JRE sees two command line arguments: param1 and param2.

With the logical JAVA$DISABLE_CMDFILE_WHITESPACE_PARSING defined, the JRE 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 DUKE.RUNNING.GIF cannot be created.

On OpenVMS, the JRE 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 DUKE_RUNNING.GIF.

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 JRE 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$JAVA_SHR.EXE). 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. The HotSpot VM is the only supported VM for 6.x. For more information, see Using Hotspot.

Behavior of setReadable of Class java.io.File

To make the file unreadable to the owner, an invocation of this method of the form setReadable(false,true) behaves in exactly the same way as the invocation of setReadable(false,false).

Behavior of setWriteable of Class java.io.File

To make the file unwriteable to the owner, an invocation of this method of the form setWriteable(false,true) behaves in exactly the same way as the invocation of setWriteable(false,false).

Behavior of setExecutable of Class java.io.File

To make the file unexecutable to the owner, an invocation of this method of the form setExecutable(false,true) behaves in exactly the same way as the invocation of setExecutable(false,false).

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

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

On OpenVMS systems, the JRE 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$6x_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 JRE, 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 JRE is Stream_LF. The JRE allows you to specify a logical:

$ DEFINE JAVA$CREATE_STMLF_FORMAT TRUE

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

Converting ASCII Files

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

$ CONVERT/FDL=SYS$COMMON:[JAVA$6x.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 JRE 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$6x.COM]JAVA$FILENAME_CONTROLS.COM

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

This file is called by JAVA$6x_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 JRE 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 length limit:

$ define/job JAVA$ENABLE_ENVIRONMENT_EXPANSION TRUE

When this logical is defined, the JRE will attempt to expand any logical or symbol that is preceded by "$" on the Java command line. To bypass the DCL command-line character length 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 JRE 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 JRE 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 kits 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 JDK 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 JDK kit provides examples, in SYS$COMMON:[JAVA$6x.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 JDK 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 JRE 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 JRE 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 JDK 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$6x.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 JDK 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$6x.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$6x.COM]JAVA$6x_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 JDK 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$6x.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$6x.COM]JAVA$6x_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 JRE 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 JRE 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 JRE 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 JRE supports limited file-sharing and has several user-selectable modes of file sharing. To enable JRE 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 JDK 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 JDK. The JDK then monitors when an application writes to a file, and sets a write_pending flag. Before every read operation the JDK 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 JDK.

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 JRE 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$6x_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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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 JRE 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
Layout of the Process Space

The layout of the process space has been changed for version 60, as follows:

00000000.00000000




00000000.7FFFFFFF




00000000.80000000



FFFFFFFF.7FFFFFFF




FFFFFFFF.80000000




FFFFFFFF.FFFFFFFF







P0 space



P1 space



P2 space



Pt space



S2 space



S0/S1 space





buffer for JNI code




buffer for JNI code




Java Heap



















For 6.0, the Java heap resides in P2 space. A larger memory space is now available. All the memory allocated in JNI code using the CRTL memory management routines, such as malloc, will be allocated in P0 or P1 space.

Back to top
Using GetPrimitiveArrayCritical

A copy of the primitive array is made in P0/P1 space every time GetPrimitiveArrayCritical is called. The multiple copies of the same array might be inconsistent. If the application needs only one copy of the primitive array, it can call some routines, such as IsSameObject, to make sure it hasn’t got the copy of the primitive array before calling GetPrimitiveArrayCritical.

The application should always check the return value of GetPrimitiveArrayCritical against NULL for possible out-of-memory situations.

Back to top
Using ReleasePrimitiveArrayCritical

The prototype of the ReleasePrimitiveArrayCritical is

void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)

The mode argument provides information on how the buffer should be released by the VM. It has the impact shown in the following table:

mode actions
0 copy back the content and free the carray buffer
JNI_COMMIT copy back the content but do not free the carray buffer
INI_ABORT free the buffer without copying back the possible changes

Developers should pass 0 to the mode argument to ensure consistent behavior of the application in most cases. The other options give developers more control over memory management, and should be used with extreme care.

Back to top
Using System.getenv

Similar to predefining environment variables for a process on UNIX systems, you can define a list of environment variables to be available to an OpenVMS Java application. With JDK 6.x, you can use System.getenv to build a list of environment variables.

For security reasons, we have not implemented a blind default list of environment variables. Also, we suggest keeping the variable lists to only those used by your Java application. For example, exporting the logical that points to the location of SYSUAF in a web application might be seen as a security issue because normal Web application users are not required to actually log in to the system.

By default, System.getenv builds a list of environment variables from the following four logicals:

JAVA$GETENV_PROCESS_LIST 
JAVA$GETENV_JOB_LIST 
JAVA$GETENV_GROUP_LIST 
JAVA$GETENV_SYSTEM_LIST

The following logicals are also included in the list:

HOME
USER
TERM
PATH

Rules for each item found in the list:

  1. Search the default logical name tables (lnm$file_dev):
    1. If found, build a colon separated list.
    2. If any value appears to be in OpenVMS file format, convert the name to UNIX format following the Java$filename_controls rules.
  2. If the logical is not found, Java checks for a symbol definition: Symbols are translated “as is”. OpenVMS file format is not converted.
  3. If either a logical or symbol is not found, the item is not included in the list.

Note: String System.getenv(String) is case-sensitive. Because Java for OpenVMS attempts to follow UNIX behavior, this lookup is designed to be case-sensitive. This means you must define the item in the list exactly how you would on a UNIX system. Keeping the case-sensitive property also supports the usage of the various DECC Run-Time Library (RTL) logicals that enable or disable case.

To match a true UNIX environment, define the following DECC RTL logicals as TRUE:

   DECC$EFS_CASE_PRESERVE TRUE 
   DECC$EFS_CHARSET TRUE 

And define the following DECC RTL logical as FALSE, or leave it undefined:

   DECC$EFS_CASE_SPECIAL FALSE (or not defined) 

If DECC$EFS_CASE_PRESERVE and DECC$EFS_CHARSET are not defined, or are defined as FALSE, all items in the list will be lowercased.

If DECC$EFS_CASE_SPECIAL is defined as TRUE, all items that contain all uppercase letters will appear lowercased in the list.

For example:

   $ define JAVA$GETENV_SYSTEM_LIST SYS$LOGIN, SYS$SCRATCH, SYS$DISK 
   $ define JAVA$GETENV_PROCESS_LIST foobar, testing, ZTEST ! ZTEST must be all caps 
   $ foobar == "symbol value" 
   $ define testing "logical value" 
   $ def ZTEST "ZTESTFOUND" 

System.getenv should return a string list like the following:

   foobar=>symbol value 
   XFILESEARCHPATH=>/usr/dt/app-defaults/%L/Dt 
   sys$scratch=>/SYS$SYSROOT/sysmgr 
   ZTEST=>ZTESTFOUND 
   NLSPATH=>/usr/dt/lib/nls/msg/%L/%N.cat 
   USER=>SYSTEM testing=>logical value 
   sys$disk=>/SYS$SYSROOT/sysmgr 
   sys$login=>/SYS$SYSROOT/sysmgr 
   HOME=>SYS$SYSROOT:[SYSMGR] 
   TERM=>unknown 
   PATH=>SYS$SYSROOT:[SYSMGR] 

Back to top
Controlling exit mode

Beginning with JDK 6.x, a new logical, JAVA$EXIT_ENV, is introduced to control the exit mode of the JDK. Four modes are supported:

COMPAT:

Any value returned by the exit function is masked with %x10000000.
Any value returned by waitForProcessExit is returned unchanged.
This is the mode used for all JDKs before JDK 6.x.

POSIX:

Return value of the exit function:
Any value less than 256 is converted to match the C RTL POSIX exit code.
Any value over 255 is returned as the value with the inhibit mask.

Return value of the waitForProcessExit method:
Values of 0 or 1 are returned as a 0.
The CRTL POSIX exit code 1 (3514378) is returned as a 1.
Values between 3514379 and 3516409 are converted back to POSIX-style exit values, which are from 2 to 255.

POSIXVMS:

Same as POSIX mode, with one exception: For values 0 and 1, the waitForProcessExit method is returned as 1.

POSIX0AND1:

Same as POSIX mode, with one exception: For values 0 and 1, waitForProcessExit is returned with the exact value received.

The default mode for JDK 6.x is POSIX.

Note: If your application spawns a new application by means of the Java.lang.Process that runs against a JDK whose exit mode is different from the exit mode of the current JDK, you might need to set JAVA$EXIT_ENV to an appropriate value before starting the application.

Back to top Defining RMS Record Attributes

JDK 6.0 and higher provides the capability to exercise closer control over Record Management Services (RMS) file attributes used by the CRTL library to manipulate files on behalf of the JDK. You can now override the default RMS file operation attributes with attributes of your own choosing.

This is done by defining the OpenVMS logical name JAVA$FILENAME_MATCH_LIST. The value of JAVA$FILENAME_MATCH_LIST consists of file-name patterns and RMS attributes. The RMS attributes are passed to the CRTL library by the JDK when it asks the CRTL library to manipulate files whose names match the file-name patterns.

The value consists of one or more comma-separated specifiers, where each specifier is of the form:

"file_match_pattern=<RMS parameter>/<additional RMS parameter>/<..."

Restrictions:

  • Patterns/RMS parameters cannot contain the colon ( : ) character.
  • JRE file sharing will NOT be enabled for files matching the file_match_pattern.
  • Other Java logical name settings (for example, JAVA$CREATE_STMLF) may be ignored.

Examples:

  1. $ define JAVA$FILENAME_MATCH_LIST "*.obj=ctx=stm"

    This causes the attribute "ctx=stm" to be used when the CRTL library opens a file whose name matches the pattern “*.obj”.

    Possible Usage:

    On OpenVMS Alpha, *.obj files have variable length record format with a two byte header. By default, the J2SDK relies on the CRTL library to treat all files as if they have Stream_LF record format. This causes problems when using the jar tool to create a .jar file composed of .obj files. As the CRTL library reads the .obj files it converts their records to Stream_LF record format by removing the 2 byte variable length header and adding a <LF> character to the end of each record. When the .obj files are extracted from the .jar file their two byte record header will have been lost and tools such as the OpenVMS linker will not be able to properly read these .obj files.

    You can avoid this problem by setting JAVA$FILENAME_MATCH_LIST as specified above. This will cause the jar tool to copy the .obj files into the .jar file without losing their two byte record headers. When the .obj files are restored they can then be converted back to a format that is acceptable to the OpenVMS linker by using the OpenVMS “$ set file/attr=(RFM:VAR)” command.

  2. $ define JAVA$FILENAME_MATCH_LIST "*.*=shr=get,put,upi/rop=rea"

    This is the equivalent of the following, but without JRE file sharing:

    $ define java$file_open_mode 3

  3. $ define JAVA$FILENAME_MATCH_LIST "*.exe=ctx=stm", -
    "*.pcsi_sfx_axpexe=shr=get,put,upi/rop=rea", -
    "/apache$root/logs/error*=shr=get,put,upi/rop=rea/fop=dfw,sup/mbc=127"

    This example demonstrates combining multiple settings using a single instance of JAVA$FILENAME_MATCH_LIST.

    This setting causes:

    - *.exe files to be treated as Stream_LF record format.
    - *.pcsi_sfx_axpexe files to be opened as shared.
    - /apache$root/logs/error* files to be opened as shared, with deferred write, and allocated a larger than normal Multiblock Count (mbc)

For a complete list of the RMS attributes that can be set via this mechanism, see:
http://h71000.www7.hp.com/DOC/83final/5763/5763pro_027.html#fab_rab_keywords_1.

Back to top
Using HotSpot


Using the HotSpot VM and Setting Up the Java Environment

As noted in the Introduction, the JDK 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 JDK using the default location and therefore references SYS$COMMON:[JAVA$6x] 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$6x.COM]JAVA$6x_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 "6.x"
Java(TM) SE Runtime Environment
Java HotSpot(TM) 64-bit Server VM (build 1.6.0.00 02/25/2009-14:28 IA64(c2)W, mixed mode)

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 JDK 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 Debug Wire Protocol (JDWP) and the Java Debug Interface (JDI).

  • The UsePerfData option is set to false by default. If you need to use JMX and JMM APIs, please specify -XX:+UsePerfData on the command line when invoking the Java application.

Nonstandard Options

The HotSpot technology in SDK v 6.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 JDK.

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.

-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 1MB. 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 64MB.
-Xnoclassgc Disables class garbage collection.
-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:+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 1MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. Default for SDK v 1.5.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:SurvivorRatio=<size> Ratio of eden/survivor space size. Default for SDK v 1.5.x is 8. If your new generation heap is 100MB, the space reserved for objects to survive a GC is ½*(100MB/8), or 6.25MB. 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://docs.hp.com/en/JAVAPROGUIDE/index.html.

The SDK v 6.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://docs.hp.com/en/JAVAPROGUIDE/xverbosegc_5.0.html.

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

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 JRE 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 Technology web site.

Note: The minimum version of Secure Web Browser (SWB) that supports JDK 6.x is SWB 1.7-8 based on Mozilla®, or SWB 1.1-12 based on SeaMonkey.

Note: For simplicity, this document assumes you installed the JDK using the default location and therefore references SYS$COMMON:[JAVA$6x] 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 SWB and the Plug-In

Note: These instructions are written for SWB based on Mozilla, but the instructions for SWB based on SeaMonkey are similar.

To install Mozilla:

  1. Download SWB.
  2. Refer to the HP Secure Web Browser for OpenVMS I64 (based on Mozilla) Installation Guide and Release Notes to install Mozilla on your system.

To run SWB:

$ @SYS$COMMON:[CSWB]MOZILLA

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

If you spawn it off as a subprocess:

$ spawn/nowait @SYS$COMMON:[CSWB]MOZILLA

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

To enable the JRE within your browser:

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

  3. When both JDK 6.x and CSWB 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$6x.JRE.PLUGIN.IA64.NS7]LIBJAVAPLUGIN_OJI.SO -
    SYS$COMMON:[CSWB.PLUGINS]
    where x is the specific version number of the release you are using. Thereafter, you can set up for Java operation:
    $ @SYS$COMMON:[JAVA$6x.COM]JAVA$6x_SETUP.COM
    where x is the specific version number of the release you are using.


  4. Then run SWB:
    $ @sys$common:[CSWB]mozilla
    SWB 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

SWB 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$6x.JRE.PLUGIN.IA64.NS7]LIBJAVAPLUGIN_OJI.SO -
SYS$COMMON:[CSWB.PLUGINS]

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

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]

To use this "private" plug-ins area:

$ copy /PROT=W:RE -
SYS$COMMON:[JAVA$6x.JRE.PLUGIN.IA64.NS7]LIBJAVAPLUGIN_OJI.SO -
USERS:[FLINTSTONE._MOZILLA.PLUGINS]

Essentially, if you place a LIBJAVAPLUGIN_OJI.SO into USERS:[FLINTSTONE._MOZILLA.PLUGINS], it will be used by Mozilla and override what is in SYS$COMMON:[CSWB.PLUGINS].

The Plug-in Control Panel

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

$ ControlPanel

Please refer to Sun's Java Control Panel 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 JDK release includes the following font support.

Role of the font configuration File

Starting with JDK 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 for previous releases, was installed in SYS$COMMON:[JAVA$1xx.JRE.LIB]FONT.PROPERTIES, where x is the specific version number of the release you are using. Starting with JDK v 5.0, font property files are no longer shipped. Instead, this version uses a new font configuration file (one file is used by all locales) to map the logical font names to physical fonts. It identifies fonts that should be available on your X server. Where possible, the font configuration file uses Lucida fonts which are bundled with and ship on the kit. This allows for greater consistency across Java applications using the same JDK. Therefore, you might notice some differences in your window displays because of the fonts now being 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 configuration file for your use, copy the file installed by this kit from [.JRE.LIB]fonconfig_properties.src to fontconfig.properties in the same directory and modify it. When you run a Java application, it will use your newly modified source font configuration file fontconfig.properties instead of the binary file fontconfig.bfc installed by this kit.

Note: For simplicity, this document assumes you installed the JDK using the default location and therefore references SYS$COMMON:[JAVA$6x] 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 configuration Files Provided

It is difficult to supply a font configuration 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 two font configuration files:

  • fontconfig.bfc

    This binary file is used when displaying your application to OpenVMS and Tru64 UNIX workstations, or to PCs running the DIGITAL eXcursion™ window manager.

  • fontconfig_properties.src

    This source file is for reference only. To change the fonts your application uses, you can use this file as a basis for a fontconfig.properties which would take precedence over the binary file.

Both of these files reside in [.JRE.LIB], and the one named fontconfig.bfc 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 JDK supports customizations of the font configuration file which can take affect on a system-wide basis. When the JRE needs to find a font configuration file, it searches this directory.

If you prefer to use fonts other than those that have been predefined by the font configuration file for your use, copy the file installed by this kit from [.JRE.LIB]fontconfig_properties.src to fontconfig.properties in the same directory and modify it. When you run a Java application, it will use your new font configuration file instead of the binary file.

$ COPY SYS$COMMON:[JAVA$6x.JRE.LIB]fontconfig_properties.src -
       SYS$COMMON:[JAVA$6x.JRE.LIB]fontconfig.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 JDK kit, you would delete your new file fontconfig.properties.

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. If you encounter one of the following warnings, you are probably referencing a font in your font configuration 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 configuration file references fonts that are installed on your system; you may be attempting to use a font that is not available.

Warning: Cannot convert string "...." to type FontStruct

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 configuration 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.

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
Resolving Domain Names in Java

Domain-name resolving can be done by the sockets API or the JDK itself. To make domain-name resolving work in the JDK on OpenVMS systems, you must configure your system as follows:

  1. Configure the BIND resolver using the ASCII configuration file TCPIP$ETC:RESOLV.CONF. For more information, refer to the document HP TCP/IP Services for OpenVMS Management.

  2. Add the directory map into the java$filename_controls logical:
    $ show log java$filename_controls 
           "JAVA$FILENAME_CONTROLS" = "131592" (LNM$JOB_899A9900) 
    If the directory mapping bit is not set as in the above example, set it as follows: 
    $ b=131592+536870912 ! add in the directory mapping bit 
    $ show sym b 
      B = 537002504 Hex = 20020208 Octal = 04000401010 
    $ def java$filename_controls 537002504 
  3. Direct java to get the DNS configuration from /sys$system/resolv.conf instead of /etc/resolv.conf:
    $ DEF JAVA$DIRECTORY_MAPPING_COUNT 1
    $ DEF JAVA$DIRECTORY_MAPPING_01 "/etc/resolv.conf=/sys$system/resolv.conf" 
    

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 JRE sees it and tabulates the argument list before the JRE 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 JRE dumps out all the Java thread information.

This logical will only work for terminal devices, when the JRE 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 JRE 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 JRE 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 JRE.

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$6x.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 JDK 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 JRE. 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 JDK 6.0, or the Release Notes for JDK 6.0, depending on the JDK version that you are running. You must download and install these ECOs for the JRE 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 Appendix A 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 JRE 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 JDK 6.0x documentation tree begins at the following location on the system where the JDK is installed:

SYS$COMMON:[JAVA$6x.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 JDK using the default location and therefore references SYS$COMMON:[JAVA$6x] 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:

  • The Java Platform API Specification:



    The API documentation provides brief descriptions of the API with an emphasis on specifications, not on examples.


  • The Java Class Libraries, Second Edition, published by Addison-Wesley Longman as part of The Java Series, as described on Sun's site. These volumes include much more elaborate descriptions, with definitions of terminology and examples for practically every class, interface, and member.

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 JDK 6.0 software from Sun Microsystems, and the Release Notes for this JDK.

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.

© 2009 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 trademarks and logos are trademarks or registered trademarks of Oracle America and/or its affiliates in the United States and other countries.

Printed in the US

Privacy statement Using this site means you accept its terms Feedback to Webmaster
© 2011 Hewlett-Packard Development Company, L.P.