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.
2 comments:
This problem has been fixed in IKVM 0.36.0.11.
Super! That's what I get for not having updated since the the end of last year (still on 0.36.0.5 here).
Post a Comment