динамично создайте класс в scala, я должен использовать интерпретатор?

Я хочу создать класс во времени выполнения в Scala. На данный момент просто рассмотрите простой случай, где я хочу сделать эквивалент боба Java с некоторыми атрибутами, я только знаю эти атрибуты во время выполнения.

Как я могу создать scala класс? Я готов создать из scala исходного файла, если существует способ скомпилировать его и загрузить его во время выполнения, я могу хотеть, поскольку у меня иногда есть некоторая комплексная функция, я хочу добавить к классу. Как я могу сделать это?

Я волнуюсь, что scala интерпретатор, который я считал о действительно ли игре в песочнице, является интерпретируемым кодом, который это загружает так, чтобы это не было доступно общему применению, размещающему интерпретатор? Если это верно, затем я не смог бы использовать динамично загруженный scala класс.

Так или иначе вопрос, как я могу динамично создать scala класс во время выполнения и использовать его в моем приложении, лучший случай должен загрузить его из scala исходного файла во время выполнения, что-то как interpreterSource("file.scala") и его загруженное в мое текущее время выполнения, почти лучший случай является некоторым созданием вызывающими методами т.е. createClass(...) создать его во времени выполнения.

Спасибо, Phil

12
задан AdrieanKhisbe 19 February 2015 в 21:17
поделиться

1 ответ

Здесь недостаточно информации, чтобы знать лучший ответ, но помните, что вы работаете на JVM, поэтому любые методы или библиотеки для разработки байткода, применимые для Java, должны быть применимы и здесь.

Существуют сотни методов, которые вы можете использовать, но лучший выбор полностью зависит от вашего конкретного случая использования, поскольку многие из них не являются универсальными. Вот пара идей:

  • Для простого боба вы можете с тем же успехом просто использовать карту, или рассмотреть класс DynaBean из apache commons.

  • Для более продвинутого поведения вы можете явно вызвать компилятор и затем взять полученный файл .class через загрузчик классов (это в основном как это делают JSP)

  • Парсер и пользовательский DSL хорошо подходят в некоторых случаях. Также как и бобовая оболочка скриптинг.

Посмотрите видео ScalaDays здесь: http://days2010.scala-lang.org/node/138/146 в котором демонстрируется использование Scala в качестве языка сценариев, совместимого с JSR-223. Это должно покрыть большинство сценариев, в которых вы захотите оценить Scala во время выполнения.

Вы также захотите просмотреть поток сообщений здесь: http://scala-programming-language.1934581.n4.nabble.com/Compiler-API-td1992165.html#a1992165

This contains the following sample code:

// We currently call the compiler directly 
// To reduce coupling, we could instead use ant and the scalac ant task 

import scala.tools.nsc.{Global, Settings} 
import scala.tools.nsc.reporters.ConsoleReporter
{ 
  // called in the event of a compilation error 
  def error(message: String): Nothing = ... 

  val settings = new Settings(error) 
  settings.outdir.value = classesDir.getPath 
  settings.deprecation.value = true // enable detailed deprecation warnings 
  settings.unchecked.value = true // enable detailed unchecked warnings 

  val reporter = new ConsoleReporter(settings) 

  val compiler = new Global(settings, reporter) 
  (new compiler.Run).compile(filenames) 

  reporter.printSummary 
  if (reporter.hasErrors || reporter.WARNING.count > 0) 
  { 
             ... 
  } 
} 


val mainMethod: Method = { 
  val urls = Array[URL]( classesDir.toURL ) 

  val loader = new URLClassLoader(urls) 

  try { 
    val clazz: Class = loader.loadClass(...) 

    val method: Method = clazz.getMethod("main", Array[Class]( classOf[Array[String]] )) 
    if (Modifier.isStatic(method.getModifiers)) { 
       method 
    } else { 
      ... 
    } 
  } catch { 
    case cnf: ClassNotFoundException => ... 
    case nsm: NoSuchMethodException => ... 
  } 
} 

mainMethod.invoke(null, Array[Object]( args )) 
8
ответ дан 2 December 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: