如何使用上下文应用程序的类路径创建GroovyShell对象

时间:2012-01-04 04:20:35

标签: groovy dsl

对于背景,我正在尝试编写一个DSL解析器,使用这个伟大的example。不幸的是,当我调整此行以在我自己的应用程序中使用时:

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

我在运行时遇到类解析错误,因为我的DSL域文件具有引用其他外部类的代码。上下文应用程序可以访问这些类,但我不知道如何将它们访问到新的GroovyShell对象,或者以某种方式使用上下文应用程序的运行时环境来解析文件。

2 个答案:

答案 0 :(得分:8)

您是否尝试过使用以下构造函数:public GroovyShell(ClassLoader parent)

像这样:Script dslScript = new GroovyShell(this.class.classLoader).parse(dsl.text)

希望有帮助...

答案 1 :(得分:8)

这是一个代码片段,展示了如何注入上下文对象,配置属性和类路径。

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();
}

请注意,此代码还会注入基类,以便对属性解析和对不同DSL文件之间的继承的支持进行细粒度控制。 有关Cloudify项目的更多信息和工作源代码,请参阅 http://cloudifysource.tumblr.com/post/23046765169/parsing-complex-dsls-using-groovy