JVM Enabled languages

Other than Java language on any JVM it is possible to execute code written in other languages. Some examples of JVM enabled languages are Scala, Kotlin, an extended list is available on https://en.m.wikipedia.org/wiki/List_of_JVM_languages.

With JCOBridge it is possible to use all libraries available without any limitation, just setup the environment and use them as you can do from Java. Here below an example of the use of the Scala Language from JVM and CLR.

JVM/Scala REPL

scala REPL shell using .NET

JVM/Scala from CLR/C#

Here below a simple Scala class

import java.lang._

final class ScalaClass(aString: String, val anInteger: Int) {
    def this() {
        this("defaultString", -1)
    }

    def this(aBool: Boolean) {
        this("defaultString", -1)
    }

    val scalaString = "This is a Scala String"

    def add(x: Int, y: Int): Int = x + y

    def stringConcat(args: Array[String]): String = 
    {
        return args.mkString(", ")
    }
}

Here below the C# code, with initialization to use Scala, which invokes the method within the scala class.

using MASES.JCOBridge.C2JBridge;
using System;
using System.Collections.Generic;
using System.IO;

namespace ScalaClassUseExample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                JCOBridge.Initialize("");
            }
            catch (Exception e) { Console.WriteLine(e.Message); }
            TestClass Test = new TestClass();
            Test.Execute();
        }

        class TestClass : SetupJVMWrapper
        {
            public override string ClassPath
            {
                get
                {
                    string scalaBasePath = @"C:\Program Files (x86)\scala\lib";

                    var basePath = @"C:\Program Files\MASES Group\JCOB\Core;..\..\JVM\Scala\Output;";
                    basePath += Path.Combine(scalaBasePath, "jline -2.14.6.jar") + ";";
                    basePath += Path.Combine(scalaBasePath, "scala-compiler.jar") + ";";
                    basePath += Path.Combine(scalaBasePath, "scala-library.jar") + ";";
                    basePath += Path.Combine(scalaBasePath, "scala-parser-combinators_2.12-1.0.7.jar") + ";";
                    basePath += Path.Combine(scalaBasePath, "scala-reflect.jar") + ";";
                    basePath += Path.Combine(scalaBasePath, "scala-swing_2.12-2.0.3.jar") + ";";
                    basePath += Path.Combine(scalaBasePath, "scala-xml_2.12-1.0.6.jar") + ";";
                    basePath += Path.Combine(scalaBasePath, "scalap-2.12.8.jar") + ";";
                    return basePath;
                }
            }
            public override string JVMPath { get { return null; } }

            public void Execute()
            {
                int a = 10;
                int b = 15;
                var scalaClass = DynJVM.ScalaClass.@new();
                var result = scalaClass.add(a, b);
                Console.WriteLine("{0} + {1} = {2}", a, b, result);

                List<string> strings = new List<string>(new string[] { "One", "Two", "Three" });
                var concatString = scalaClass.stringConcat(strings.ToArray());
                Console.WriteLine("{0} = {1}", strings, concatString);

                Console.WriteLine("Press Enter to exit");
                Console.ReadLine();
            }
        }
    }
}

CLR/.NET from JVM/Scala

Here below a Scala program which use native .NET objects:

import java.util.Iterator
import org.mases.jcobridge._

object Main extends App {
  try
  {
    JCOBridge.Initialize("");
  }
  catch
  {
    // catch to avoid problem with Trial mode of JCOBridge
    case jce: JCException => System.out.println(jce.getMessage)
  }

  val bridge = JCOBridge.CreateNew()

  // adds a new reference to WPF 
  bridge.AddReference("PresentationFramework")
  // get MessageBox type
  val msgType = bridge.GetType("System.Windows.MessageBox")
  // invoke static method to show a message box on the screen
	msgType.Invoke("Show", "Please press enter to continue")

  // get .NET type
  val enumType = bridge.GetType("System.Environment")
  // invokes static method
	val genObj = enumType.Invoke("GetLogicalDrives")
  // retrieve the iterator
  val iteratorObj = genObj.asInstanceOf[JCObject].iterator
  // iterate on all object and print the value
  while (iteratorObj.hasNext) println(iteratorObj.next)

  // invoke static method to show a message box on the screen
	msgType.Invoke("Show", "Please press enter")

  // event callback example
  val tObj = bridge.NewObject("System.Timers.Timer"); // create the timer object
  val timerObj = tObj.asInstanceOf[JCObject];
  // register an event handler when the Timer elaps
  timerObj.RegisterEventListener("Elapsed", new ScalaJCVoidEventEmit()); 
  // set Interval property
  timerObj.Set("Interval", 1000); // set properties
  // enable the Timer
  timerObj.Set("Enabled", true); // start timer

  // invoke static method to show a message box on the screen
	msgType.Invoke("Show", "Please press enter")
}

final class ScalaJCVoidEventEmit() extends JCVoidEventEmit {
  override def EventRaised(args: Object*) : Unit =
  {
		// scala seems to have a problem to translate var args argument into JVM bytecode. This method is needed to avoid compilation problems
  }
  // this method defines exactly the signature expected from the event
  def EventRaised(sender: Object, arg: Object) : Unit =
  {
		println("Timer Elapsed")
  }
}