Ответ 1
Недостаточно информации, чтобы узнать лучший ответ, но помните, что вы работаете на JVM, поэтому все методы или библиотеки инструментов байт-кода, действительные для Java, также должны быть здесь действительны.
Существуют сотни методов, которые вы можете использовать, но лучший выбор полностью зависит от вашего конкретного варианта использования, поскольку многие из них не являются универсальными. Вот пара идей, хотя:
-
Для простого bean вы можете также просто используйте карту или посмотрите на Класс DynaBean из сообщества apache.
-
Для более продвинутого поведения вы можете вызывать компилятор явно и затем возьмите полученный файл .class через загрузчик классов (это в значительной степени как это делают JSP)
-
Анализатор и пользовательский DSL хорошо вписываются в в некоторых случаях. Как и оболочка bean сценариев.
Посмотрите видео 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
Здесь содержится следующий пример кода:
// 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 ))