And although I could use Jni4Net to create a bridge between a JVM and the CLR, it would be much nicer if I could write Groovy scripts under the CLR (with live access the FluentSharp APIs and O2 created objects).
And by using IKVM I was able to do exactly that :)
I was able to convert the main Groovy jar JVM bytecode into .NET CLR bytecode, and evaluate Groovy scripts directly in C# (i.e. without a JVM loaded in the current process). For more O2 usage of the amazing IKVM API's see Util - O2 Java Tools (IKVM Based) v1.0
Evaluating an Groovy script in .NET:
After created the groovy-all-2.1.6.dll .Net IKVM dll (see Appendix 1) Creating groovy-all-2.1.6.dll below), I was able to consume it (in O2’s C# REPL) like this:
The screenshot above is quite an amazing achievement, since what we have there is the pure .NET execution of the “40 + 2” groovy script :)
For example here is a new instance of the Java ProcessBuilder object (created outside an Java based JVM)
Which can be used in Groovy-style to start calc:
And for an even more interesting example, the line 4 of the script below
... will open the GroovyConsole, which is a Swing application running under the CLR!!!
From here we can execute groovy scripts, like this one:
... like this (with an error):
… or like this:
Next thing to try is if are able to access .NET Apis from this Groovy environment.
Using the UI described in Appendix 2) Creating a simple Groovy REPL UI (see below) here is how to access MSCorLib.dll apis from the Groovy Java scripting environment:
For that to work we need first to create the mscorlib.jar so that the ‘CLR-based JVM’ can find the clr.System.IO.* classes (see IKVM’s Develop a .NET Application in Java article for more details)
This is done using the command: ikvmstub -out:dlls/mscorlib.jar mscorlib which will create the respective mscorlib.jar
Next let’s access some of FluentSharp APIs.
As with mscorlib, we start by creating the FluentSharp.CoreLib.jar using ikvmstub -out:dlls/FluentSharp.CoreLib.jar -r:C:\Windows\assembly\GAC_MSIL\
\System.Core.dll E:\O2\_Source_Code\FluentSharp\FluentSharp.O2Platform\bin\Debug\FluentSharp.CoreLib.dll (note the extra reference to System.Core.dll)
We can then consume the fluentSharp.CoreLib.jar like this:
Since FluentSharp.CoreLib.dll had more dependencies, I used this script:
//var topPanel = "{name}".popupWindow(700,400); var ikvmFolder = @"C:\Users\o2\AppData\Roaming\OWASP_O2_Platform_5.3\_ToolsOrApis\IKVM\ikvm-7.2.4630.5\bin"; var targetJar = ikvmFolder.pathCombine(@"dlls\FluentSharp.WinForms.jar"); var ikvmStub = ikvmFolder.pathCombine("ikvmstub.exe"); var arguments = "-out:\"{0}\" ".format(targetJar) + @" -r:C:\Windows\assembly\GAC_MSIL\System.Core\3.5.0.0__b77a5c561934e089\System.Core.dll" + @" -r:C:\Windows\assembly\GAC_MSIL\System.Xml.Linq\3.5.0.0__b77a5c561934e089\System.Xml.Linq.dll" + " \"{0}\"".format("FluentSharp.WinForms.dll".assembly_Location()); return ikvmStub.startProcess_getConsoleOut(arguments);
Here is how to get a class to one of FluentSharp extension methods helper classes:
... and here is how to invoke it:
ok, the code above (using the Extension Method static invocation) it is not as user friendly as the normal FluentSharp code:
"This is a Groovy Form".popupWindow()
....but with a couple custom groovy builders, we should get there :)
(the rest of this post contains the 2 appendixes referenced above)
Appendix #1: Creating groovy-all-2.1.6.dll
Similar to the process described at Running Groovy on .NET 2.0 using IKVM and Groovy running fine on .NET (both posted in 2007) I wrote this O2 Installer script:
... which uses the (already existing) IKVM API to create the dll:
Once that installer executes (with a bunch of warnings shown on the log viewer), we have the desired groovy-all-2.1.6.dll file created (which is a .NET version of the Java jar file):
Appendix 2) Creating a simple Groovy REPL UI
There are already a number of FluentSharp APIs that allow the easy creation of REPL UIs. For example:
... which can be easily extended to support the groovy evaluate capabilities
... and looks like this when executed:
... and like this (after making it a popupWindow)
After saving this script as Util - Simple Groovy Shell.h2
... we can execute it as a normal O2 tool:
Note how the groovy Binging object is holding the objects created during multiple executions (i.e. the calc variable was set during the first execution (shown above)):