2010-05-02 10 views
12

Quiero crear una clase en tiempo de ejecución en Scala. Por ahora, solo considere un caso simple en el que quiero hacer el equivalente de un bean Java con algunos atributos, solo conozco estos atributos en tiempo de ejecución.crea dinámicamente la clase en scala, ¿debería usar intérprete?

¿Cómo puedo crear la clase scala? Estoy dispuesto a crear desde el archivo fuente de scala si hay una forma de compilarlo y cargarlo en tiempo de ejecución, es posible que desee ya que a veces tengo alguna función compleja que deseo agregar a la clase. ¿Cómo puedo hacerlo?

Me preocupa que el intérprete de scala sobre el que he leído esté guardando el código interpretado que carga para que no esté disponible para la aplicación general que aloja el intérprete. Si este es el caso, entonces no podría usar la clase scala cargada dinámicamente.

De todos modos, la pregunta es cómo puedo crear dinámicamente una clase scala en tiempo de ejecución y usarla en mi aplicación, lo mejor es cargarla desde un archivo fuente scala en tiempo de ejecución, algo así como interpreterSource("file.scala") y cargarla en mi tiempo de ejecución actual, el segundo mejor caso es una creación llamando al método , es decir.createClass(...) para crearlo en tiempo de ejecución.

Gracias, Phil

Respuesta

7

no hay suficiente información para saber la mejor respuesta, pero recuerde que se está ejecutando en la JVM, por lo que cualquiera de las técnicas de ingeniería o bibliotecas de código de bytes válidos para Java también debe ser válido aquí.

Existen cientos de técnicas que puede utilizar, pero la mejor opción depende totalmente de su caso de uso exacto, ya que muchas no son de propósito general. Aquí hay un par de ideas sin embargo:

  • Para un grano simple, es posible que así sólo tiene que utilizar un mapa, o buscar en la clase DynaBean de apache commons.

  • Para un comportamiento más avanzada que podría invocar el compilador de forma explícita y a continuación, coger el archivo .class resultante a través de un cargador de clases (esto es en gran parte cómo lo hacen JSP)

  • Un analizador y DSL ajuste personalizado bien en algunos casos. Al igual que bean shell scripting.

Mira el vídeo ScalaDays aquí: http://days2010.scala-lang.org/node/138/146 que demuestra el uso de Scala como un lenguaje de programación compatible con JSR-223. Esto debería abarcar la mayoría de los escenarios en los que le gustaría evaluar Scala en tiempo de ejecución.

También querrá buscar en el hilo de correo electrónico aquí: http://scala-programming-language.1934581.n4.nabble.com/Compiler-API-td1992165.html#a1992165

Este contiene el código de ejemplo:

// 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)) 
+0

quiero crear desde el código fuente de Scala, digamos que tengo el código fuente scala como una cadena, ¿cómo puedo hacerlo? – Phil

+0

Además de lo anterior.El siguiente enlace también puede ayudar (no pretendo ser un experto en el área): http://scala-programming-language.1934581.n4.nabble.com/Compiling-a-Scala-Snippet-at- run-time-td2000704.html – user127386

+0

Tengo problemas con el uso de este código, en particular, no puedo entender por qué pones un bloque de código justo después de la importación. ¿El código está completo o faltan algunas líneas? – mariosangiorgio

Cuestiones relacionadas