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:
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.
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 here.
VMS:
Client:
To use it:
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).
I strongly recomnmend looking at the provided examples.
<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 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:
|
Looking at the examples may be the fastest way to learn how to use TIG.
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.
For questions and comments send email to author arne@vajhoej.dk.