2016-02-12 52 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」) –