2017-10-13 65 views
1

考慮下面的代碼的方法(沒有引用它們):如何使用Groovy動態對象調用需要具體類型

def model = readMavenPom file: 'pom.xml' 
dep = [ 
    groupId : "org.foo", 
    artifactId : "bar", 
    version : "1.0" ] 

我想打電話給Model.addDependency

model.addDependency(dep) 

這給了錯誤

抓住:groovy.lang.MissingMethodException:沒有方法的簽名:org.apache.maven.model.Model.addDependency()是appli電纜參數類型:(java.util.LinkedHashMap中)的值:[[的groupId:org.foo,artifactId的:巴,版本:1.0]]

現在可以做到

model.addDependency(dep as Dependency) 

引用類時。它工作沒有問題。本地。

不幸的是,我必須執行對詹金斯,和我遇到了這個issue。所以基本上,如果我參考Dependency類,我遇到了一些類加載問題。有建議使用「動態打字」。

因此,它是可以調用addDependency沒有引用這門課嗎?

+0

這似乎是不可能的。您需要創建一個'Dependency'對象或將一個'Map'實例投射到它。 – Opal

+0

我想不出一個簡單的方法來測試這個,但試試這個。如果它有效,我會將它轉換成答案。如果運氣好的話,parameterTypes會把從Model的類加載器中解析出來的Class取出來,而不是腳本自己。 > model.addDependency(模型&addDependency.parameterTypes [0] .newInstance(DEP)) – Corrodias

+0

@Corrodias:因此,這基本上意味着通過反射來訪問該類別?它可能工作,但不幸的是我現在無法測試,因爲代碼在Jenkins的常規沙箱中運行,不允許使用這些方法,所以我必須等到它被管理員批准爲止。 (也許在星期一) – user140547

回答

1

問題是,加載Model類(我們稱之爲「A」)的類加載器與您在引用依賴類(「B」)時嘗試使用的腳本不同。所以你可以用你的classloader-B創建一個Dependency-B,但是Model-A需要一個Dependency-A。

我們可以使用反射來獲取到相關-A類的引用,然後創建使用相同的屬性映射一個它的實例,就像這樣:

def model = readMavenPom file: 'pom.xml' 
dep = [ 
    groupId : "org.foo", 
    artifactId : "bar", 
    version : "1.0" ] 
model.addDependency(model.&addDependency.parameterTypes[0].n‌​ewInstance(dep)) 

在Groovy,& addDependency是一個方法引用,反射風格。我們肯定知道這個名稱只有一個方法,並且它只有一個參數,所以我們只需要第一個參數的類並調用newInstance,它與「as」關鍵字的作用方式相同。

相關問題