2017-10-13 1 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.addDependency(モデル。&addDependency.parameterTypes [0] .newInstance(dep)) – Corrodias

+0

@Corrodias:これは基本的にリフレクションによってそのクラスにアクセスすることを意味しますか?それはうまくいくかもしれませんが、残念ながら、コードがそのメソッドを許可しないJenkinsのGroovy Sandboxで実行されるため、私はそれをテストできません。管理者が承認するまで待たなければなりません。 (おそらく月曜日) – user140547

答えて

1

問題は、Modelクラスを読み込んだクラスローダー(「A」と呼ぶ)が、Dependencyクラス(「B」)を参照するときにスクリプトが使用しようとしているものと同じではないということです。つまり、クラスローダー-BでDependency-Bを作成できますが、Model-AではDependency-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)) 

、& addDependencyはメソッド参照であります、反射スタイル。その名前のメソッドは1つしかなく、パラメータは1つしかないので、最初のパラメータのクラスを取り、newInstanceを呼び出します。これは、 "as"キーワードと同じように機能します。

関連する問題