jeudi 29 novembre 2018

Dynamically create scala class type

I need to provide a type for external library. In this library, the constructor with single String parameter is found and executed to create an instance of a specific class:

class Base(path: String) {
   // some code here
}

def createClass(className: String): Unit = {
  val clazz: Class[_] = Class.forName(className).asInstanceOf[Class[Base]]
  val ctor: Constructor[_] = clazz.getDeclaredConstructor(classOf[String])
  val outputPath: String = "Dummy" // provided dynamically by framework
  ctor.newInstance(outputPath)
}

I want to provide a code that will invoke createClass method to print 2 different numbers:

printDynamic(42) // int values are generated after program starts
printDynamic(24)

Question: how do I implement printDynamic in the way that doesn't have hardcode or global variables?

My current implementation uses global vars:

def execDynamic(param: Int): Unit = {
  Holder.externalValue = param
  createClass("com.test.StaticPrinter")
}
... other file
package com.test

class StaticPrinter(path: String) {
  println(path + Holder.externalValue)
}

object Holder {
  var externalValue: Int = _ 
}

I would like to generate classes on the fly, but I don't know of the way to do that. Something like this:

def execDynamic(param: Int)= {
  val clazz: Class[_] = magicallyCreateClass_WithSingleStringConstructor(param)
  createClass(clazz.getName)
}

Will I be forced to do bytecode manipulation for this or scala provides some code-generating capabilities that fit?





Aucun commentaire:

Enregistrer un commentaire