Compile & load an external scala file in your application


Some days ago, i got a requirement that i need to load an external scala file in my Scala application and have to use that. To use that file, it needs to be compile first and then can be used in the application.

The location of that external file can be anything apart from your project.

The structure of external file is fixed and should be define in your project i.e. class name and method signature.

abstract class ExternalProcessing {
  def process(a: Int, b: Int): Int
}

Arguments and return type of the method can be vary according to our requirement.

Firstly we will define the dependencies in build.sbt :

 "org.scala-lang" % "scala-reflect" % "2.11.8",
 "org.scala-lang" % "scala-compiler" % "2.11.8"

Now, we need to define the code which will compile and load the external file in our application.

case class LoadExternalScalaFile(filePath: String) {
  val toolbox = currentMirror.mkToolBox()
  val fileContents = Source.fromFile(filePath).getLines().mkString("\n")
  val tree = toolbox.parse(s"import com.rishi._;$fileContents")
  val compiledCode = toolbox.compile(tree)

  def getFileReference: ExteranlProcessing = compiledCode().asInstanceOf[ExteranlProcessing]
}

filePath is the path of external file which needs to be loaded.
You will notice the import statement as well :

"import com.rishi._"

This import is there because abstract class ExternalProcessing needs to be import in external file code as well otherwise type ExteranlProcessing not found compile time error will be there.

Now, we need to use externally loaded file as below:

val externalFile = LoadExternalScalaFile(filePath)
val externalProcessing = externalFile.getFileReference
externalProcessing.process(data.a, data.b)

Full code :

package com.rishi

import java.io.File

import scala.io.Source
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox

abstract class ExteranlProcessing {
  def process(a: Int, b: Int): Int
}

case class Input(a: Int, b: Int)

case class LoadExternalScalaFile(filePath: String) {
  val toolbox = currentMirror.mkToolBox()
  val fileContents = Source.fromFile(filePath).getLines().mkString("\n")
  val tree = toolbox.parse(s"import com.rishi._;$fileContents")
  val compiledCode = toolbox.compile(tree)

  def getFileReference: ExteranlProcessing = compiledCode().asInstanceOf[ExteranlProcessing]
}

class ExternalScalaFileHelper {
  def processExternalFile(filePath: String, data: Input): Either[String, Int] = {
    try {
      if (new File(filePath).exists()) {
        val externalFile = LoadExternalScalaFile(filePath)
        val externalProcessing = externalFile.getFileReference
        Right(externalProcessing.process(data.a, data.b))
      } else Left("Incorrect file path")
    } catch {
      case ex: Exception = Left(ex.getMessage)
    }
  }
}

Get full code here

Hope this will be useful for you.

Happy Blogging. !!!

About Rishi Khandelwal

Sr. Software Consultant having more than 6 years industry experience. He has working experience in various technologies such as Scala, Java, Play, Akka, Spark, Hive, Cassandra, Akka-http, ElasticSearch, Backbone.js, html5, javascript, Less, Amazon EC2, WebRTC, SBT
This entry was posted in Scala. Bookmark the permalink.

One Response to Compile & load an external scala file in your application

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s