Я хочу создать класс во времени выполнения в Scala. На данный момент просто рассмотрите простой случай, где я хочу сделать эквивалент боба Java с некоторыми атрибутами, я только знаю эти атрибуты во время выполнения.
Как я могу создать scala класс? Я готов создать из scala исходного файла, если существует способ скомпилировать его и загрузить его во время выполнения, я могу хотеть, поскольку у меня иногда есть некоторая комплексная функция, я хочу добавить к классу. Как я могу сделать это?
Я волнуюсь, что scala интерпретатор, который я считал о действительно ли игре в песочнице, является интерпретируемым кодом, который это загружает так, чтобы это не было доступно общему применению, размещающему интерпретатор? Если это верно, затем я не смог бы использовать динамично загруженный scala класс.
Так или иначе вопрос, как я могу динамично создать scala класс во время выполнения и использовать его в моем приложении, лучший случай должен загрузить его из scala исходного файла во время выполнения, что-то как interpreterSource("file.scala")
и его загруженное в мое текущее время выполнения, почти лучший случай является некоторым созданием вызывающими методами т.е. createClass(...)
создать его во времени выполнения.
Спасибо, Phil
Здесь недостаточно информации, чтобы знать лучший ответ, но помните, что вы работаете на 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 ))