2012-01-04 4 views
5

Para el fondo, estoy experimentando con la escritura de un analizador de DSL, usando este gran example. Por desgracia, cuando me adapto esta línea para su uso en mi propia aplicación:Cómo crear un objeto de GroovyShell con classpath de la aplicación de contexto

Script dslScript = new GroovyShell().parse(dsl.text) 

, recibo errores de resolver las clases de tiempo de ejecución, como los archivos de mi dominio DSL tienen código que hace referencia a otras clases externas. La aplicación de contexto tiene acceso a estas clases, pero no sé cómo darles acceso al nuevo objeto de GroovyShell o, de forma alternativa, utilizar el entorno de tiempo de ejecución de la aplicación de contexto para analizar el archivo.

Respuesta

6

¿Ha intentado utilizar el siguiente constructor: public GroovyShell(ClassLoader parent)

De esta manera: Script dslScript = new GroovyShell(this.class.classLoader).parse(dsl.text)

Espero que ayude ...

+0

Sí. Acabo de llegar a una solución similar desde esto en Grails: Script dslScript = new GroovyShell (grailsApplication.classLoader) .parse (dsl.text) –

+0

Esto soluciona los problemas con PermSpace, donde esto deja la información de la clase allí y la puede ejecutar fuera de PermSpace eventualmente? Vea aquí: http://stackoverflow.com/questions/24169976/understanding-groovy-grails-classloader-leak https://issues.apache.org/jira/browse/GROOVY-2875 Por lo tanto, me pregunto si esto se puede recomendar para aplicaciones de servidor o no, –

+0

Ha pasado un tiempo, pero me imagino que todavía está compilando una nueva clase. Si ese es el caso, el efecto será similar a 'parseClass' – clmarquart

7

Aquí es un fragmento de código que muestra cómo inyectar un objeto de contexto, configuración propiedades y el classpath.

Service parse(
String dslFile, List<String> classpath, 
Map<String, Object> properties, ServiceContext context) { 

// add POJO base class, and classpath 
CompilerConfiguration cc = new CompilerConfiguration(); 
cc.setScriptBaseClass(BaseDslScript.class.getName()); 
cc.setClasspathList(classpath); 

// inject default imports 
ic = new ImportCustomizer(); 
ic.addImports(ServiceUtils.class.getName()); 
cc.addCompilationCustomizers(ic); 

// inject context and properties 
Binding binding = new Binding(); 
binding.setVariable("context", context); 
for (prop: properties.entrySet()) { 
    binding.setVariable(prop.getKey(), prop.getValue()); 
} 

// parse the recipe text file 
ClassLoader classloader = this.class.getClassLoader(); 
GroovyShell gs = new GroovyShell(classloader, binding, cc); 
FileReader reader = new FileReader(dslFile); 
try { 
    return (Service) gs.evaluate(reader); 
} finally { 
    reader.close(); 
} 

Tenga en cuenta que este código también se inyecta la clase base con el fin de hacerse con el control de grano fino en el análisis de la propiedad y el apoyo a la herencia entre los diferentes archivos de DSL. Para obtener más información y código fuente de trabajo del proyecto Cloudify, consulte http://cloudifysource.tumblr.com/post/23046765169/parsing-complex-dsls-using-groovy

Cuestiones relacionadas