So, we have pure J#. Where do we go from here?
C#
The body of the driver class carries over unchanged but for the Exception
type. The driver project has to itself reference vjslib
, as well as the jinterface
assembly but is otherwise a standard C# class-with-main, and "just works".
using System;
using com.ericsson.otp.erlang;
public class ClientNode
{
[STAThread]
public static void Main(System.String[] _args)
{
OtpSelf cNode = new OtpSelf("clientnode", "cookie");
OtpPeer sNode = new OtpPeer("servernode@chloe.ravnaandtines.com");
OtpConnection connection = cNode.connect(sNode);
OtpErlangObject[] args = new OtpErlangObject[]{new OtpErlangLong(1), new OtpErlangLong(2)};
connection.sendRPC("mathserver", "add", args);
OtpErlangLong sum = (OtpErlangLong) connection.receiveRPC();
if (sum.intValue() != 3)
{
throw new System.SystemException("Assertion failed, returned = " + sum.intValue());
}
System.Console.Out.WriteLine("OK!");
}
}
How do we divest ourselves of the dependency on the J# runtime?
The Java Language Conversion Assistant generates C# code that doesn't compile, and would require a moderate amount of patching up for differences between superficially similar API classes. It is by no means a one evening exercise.
The OtpErlang.jar
similarly fails to be converted by the jbImp
tool, but IKVM converts it nicely; so at the penalty of having 27Mb worth of IKVM.OpenJDK.ClassLibrary.dll
and IKVM.Runtime.dll
instead of 3.7Mb of J#, driving the ~100kb dll, you can build the C# program and it passes this simple proof of concept.
IronPython and the DLR
Porting the code is easy enough
import clr
clr.AddReference("jinterface.dll")
from System import Array
from com.ericsson.otp.erlang import *
cNode = OtpSelf("clientnode", "cookie")
sNode = OtpPeer("servernode@chloe.ravnaandtines.com")
connection = cNode.connect(sNode);
args = Array[OtpErlangObject]([OtpErlangLong(1), OtpErlangLong(2)])
connection.sendRPC("mathserver", "add", args)
sum = connection.receiveRPC()
if (sum.intValue() != 3):
print "Assertion failed, returned = " + sum.intValue()
else:
print "OK!"
A direct conversion, the only slightly tricky bit being coercing the list to an Array.
This works fine when calling into the J# built library, as expected. IKVM needs the latest version -- before 0.36.0.11 (see comments), though, is a different story.
>\IronPython-2.0B1\ipy.exe Program.py
Traceback (most recent call last):
File Snippets, line unknown, in Initialize
File OtpErlang, line unknown, in connect
File OtpErlang, line unknown, in .ctor
File OtpErlang, line unknown, in .ctor
File IKVM.OpenJDK.ClassLibrary, line unknown, in .ctor
File IKVM.OpenJDK.ClassLibrary, line unknown, in init
File IKVM.OpenJDK.ClassLibrary, line unknown, in getContext
File IKVM.OpenJDK.ClassLibrary, line unknown, in getStackAccessControlContext
File IKVM.Runtime, line unknown, in getStackAccessControlContext
File IKVM.Runtime, line unknown, in GetProtectionDomainFromType
File IKVM.Runtime, line unknown, in getProtectionDomain0
File IKVM.Runtime, line unknown, in GetProtectionDomain
SystemError: The invoked member is not supported in a dynamic assembly.
Trace taken with 0.36.0.5, from last December. Fortunately, that wasn't some fundamental architectural thing being run into.