Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a GroovyShell object with context app's classpath

Tags:

groovy

dsl

For background, I am experimenting with writing a DSL parser, using this great example. Unfortunately when I adapt this line for use in my own app:

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

I get class resolve errors at runtime, as my DSL domain files have code that references other external classes. The context app has access to these classes, but I don't know how to give access to them to the new GroovyShell object, or alternatively somehow use the context app's runtime environment to parse the file.

like image 709
Josh Diehl Avatar asked Jan 04 '12 04:01

Josh Diehl


2 Answers

Have you tried using the following constructor: public GroovyShell(ClassLoader parent)

Like this: Script dslScript = new GroovyShell(this.class.classLoader).parse(dsl.text)

Hope that helps...

like image 194
clmarquart Avatar answered Sep 27 '22 19:09

clmarquart


Here is a code snippet that shows how to inject a context object, configuration properties and the 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();
}

Notice that this code also injects the base class in order to gain fine grained control on property parsing and support for inheritance between different DSL files. For more information and working source code from the Cloudify project see http://cloudifysource.tumblr.com/post/23046765169/parsing-complex-dsls-using-groovy

like image 42
itaifrenkel Avatar answered Sep 27 '22 19:09

itaifrenkel