TIG

Introduction:

TIG (Transparent Interface Gateway) enable client applications running on Windows/Linux/VMS to make remote call to native VMS code.

This is done by generating both client code and server code from a XML API definition.

High level architecture:

TIG high level architecture

Currently supported client languages:

The product is very much inspired by the old BridgeWorks product. But the IT world has evolved since then and I have some different preferences. Bridgeworks used a GUI - this use XML config file. Bridgeworks supported VMS VAX and VMS Alpha - this support VMS Alpha, VMS Itanium and VMS x86-64. Bridgeworks supported clients using Java API, Java EJB API and COM API - this supports Java, .NET, C/C++ and Python.

At the conceptual level it is also somewhat similar to CORBA, COM, Thrift, gRPC etc.. So not revolutionary in any way.

Requirements:

VMS:

Tested with VMS x86-64 + Java 8 and VMS Alpha 8.4 + Java 5.

Client:

Tested with Windows, Java 11, .NET 4.8, GCC 14.1 and CPython 3.11, but the generated client code and the support library are total standard Java/C#/C/C++/Python code and should work on any OS with any recent compiler/interpreter.

Download:

Download here.

vmstig-bin-*.zip
VMS kit
vmstig-client-*.zip
client kit
vmstig-src-*.zip
source code

Install:

VMS:

  1. unzip vmstig-bin.zip
  2. unzip -aa temp.zip
  3. @fixup

Client:

  1. unzip vmstig-client.zip

Use

To use it:

  1. make sure all native VMS functions meets API requirements - that include returning a longword status code
  2. build native VMS code to a shareable executable
  3. write XML description of API
  4. generate server code and client code from XML
  5. build server
  6. build generated client code and your client application
  7. start server
  8. run client

The command to generate server code and client code is:

java -cp vmstig.jar dk.vajhoej.vms.tig.Gen <XML file> <dir for server code> <dir for client code>

The commands to build and run the server are:

javac -cp vmstig.jar:vmscall.jar:record.jar <server name>.java
java -cp .:vmstig.jar:vmscall.jar:record.jar <server name>

If you want tot race what is going on server side add the option:

"-Djava.util.logging.config.file=jul.properties"

and modify jul.properties to log how you want (TIG is using JDK 1.4+ logger).

Documentation:

I strongly recomnmend looking at the provided examples.

Config file:

<config>
    <image>name of shreable image</image>
    <port>server listen port</port>
    <mt>multi-threaded: false/true</mt>
    <server>
        <language>dk.vajhoej.vms.tig.server.JavaServerGen</language>
    </server>
    <client>
        <language>class name of client code generator</language>
        ...
    </client>
    <methods>
        <method>
            <name>method name</name>
            <args>
                <arg>
                    <name>argument name</name>
                    <type>argument type: Word/LongWord/QuadWord/F_Float/D_Float/G_Float/S_Float/T_Float/FixedCharacterString/NullTermCharacterString/VariableCharacterString/Block</type>
                    <pass>passing mechanism: Value/Reference/Descriptor</pass>
                    <use>usage: In/InOut/Out</use>
                </arg>
                ...
        </method>
        ...
    </methods>
</config>

Blocks:

Blocks are blocks/records/structs.

Blocks require language specific treatment.

Language Blocks
Java Java class with Record annotations
C# C# class with NRecord attributes
C C struct (passed as is)
C++ C struct (passed as is)
Python Python class with:
  • a pack method that return a byte array from fields
  • an unpack method that take a byte array and populate fields

Examples provided:

Looking at the examples may be the fastest way to learn how to use TIG.

License:

How to extend:

If you need a different client API then it is possible to write your own client code generator.

Just write a class that implements dk.vajhoej.vms.tig.client.ClientGen and specify that class in the XML API definition.

A Rust client. A Go client. A PHP client. A C++ client that use Boost. A client that expose an async/reactive API. Whatever.

The wire protocol is documented in client wireprotocol.html and is really simple.

In some cases just creating a wrapper calling the C support library may be the easiest way to add a client a library, because then no need to worry about the wire protocol.

Known potential issues and TODO list:

Feedback:

For questions and comments send email to author arne@vajhoej.dk.