2016-02-12 382 views
0

我已经在我的应用程序下面的一段代码,运行脚本设置为代表Groovy的脚本BaseScript

CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); 
    compilerConfiguration.setScriptBaseClass(DelegatingScript.class.getName()); 
    GroovyShell shell = new GroovyShell(compilerConfiguration); 

    try { 
     String scriptText = ""; 
     try (Scanner scanner = new Scanner(resources[0].getInputStream())){ 
      scriptText = scanner.useDelimiter("\\A").next(); 
     } 

     DelegatingScript script = (DelegatingScript)shell.parse(scriptText); 
     script.setDelegate(this.getDelegate()); 
     script.run(); 
    } catch (IOException e) { 
     throw new IllegalArgumentException("Cannot read script resource: '" + filename + "': " + e.getLocalizedMessage(), e); 
    } 

它的工作对Groovy脚本,直到我开始重构一些功能到@BaseScript类。所以,比如我有这个Groovy类

package com.example.scripts 

abstract class MyBaseScriptClass extends Script { 
    int getTheMeaningOfLife() { 42 } 
} 

然后,我有剧本

package scripts 

import com.example.scripts.MyBaseScriptClass 
import groovy.transform.BaseScript 

@BaseScript MyBaseScriptClass baseScript 

add(context.application, 'test', theMeaningOfLife) 

它无法与错误运行:

Caused by: java.lang.ClassCastException: scripts.Script1 cannot be cast to groovy.util.DelegatingScript 
    at com.metlife.harmony.scripts.groovy.dsl.RunScript.call(RunScript.java:86) ~[classes/:?] 

也就是说,如果我在课堂上使用@BaseScript它未能将它投射到DelegatingScript?有什么解决办法吗?

+0

只是让MyBaseScriptClass延伸DelegatingScript? RunScript看起来像一个自定义代码,需要将脚本强制转换为DelegatingScript –

+0

不,扩展'DelegatingScript'不起作用。我需要将脚本强制转换为委托来为其设置一个委托'script.setDelegate(this.getDelegate());'这是一种传递执行上下文的方式 - 而不是设置绑定,这需要明确地设置变量,I只是使用委托机制。 – EvgeniySharapov

+0

我知道,但@BaseScript覆盖你的setScriptBaseClass(DelegatingScript)。你的脚本的基类是MyBaseScriptClass,这不能转换为DelegatingScript –

回答

0

为了总结注释:

@BaseScript覆盖setScriptBaseClass(DelegatingScript.class.getName())。 MyBaseScriptClass没有扩展DelegatingScript,因此RunScript中的强制转换失败。

要解决此错误,您应该更改MyBaseScript以扩展DelegatingScript。

abstract class MyBaseScriptClass extends DelegatingScript { 
    int getTheMeaningOfLife() { 42 } 
} 

如果你想绕过DelegatingScript,你应该检查脚本是DelegatingScript的一个实例吗?如果是的话,设置委托,如果不是,什么都不做?

在脚本中,你可以试着改变你的委托,但如果目前的代表并没有覆盖baseScript属性将只工作:

baseScript.delegate = baseScript 
+0

虽然这些都不能帮助我。如果我扩展'DelegatingScript',它确实解决了转换错误,但是在我的脚本中使用的所有属性(具有'@ BaseScript' anno的)都返回null。 查看'DelegatingScript'的源代码后,我发现它只是以这种方式处理的属性。方法调用工作正常。所以'我的脚本中的MeaningOfLife'返回'null',但是'getTheMeaningOfLife()'返回42. – EvgeniySharapov

+0

我想你的代表是一张地图或者其他等价物。如果找不到密钥,则让它抛出missingPropertyException。您的委托为getProperty返回null(“meaningOfLife”) –