如何使用Groovy动态对象调用需要具体类型
问题描述:
考虑下面的代码的方法(没有引用它们):如何使用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
没有引用这门课吗?
答
问题是,加载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].newInstance(dep))
在Groovy,& addDependency是一个方法引用,反射风格。我们肯定知道这个名称只有一个方法,并且它只有一个参数,所以我们只需要第一个参数的类并调用newInstance,它与“as”关键字的作用方式相同。
这似乎是不可能的。您需要创建一个'Dependency'对象或将一个'Map'实例投射到它。 – Opal
我想不出一个简单的方法来测试这个,但试试这个。如果它有效,我会将它转换成答案。如果运气好的话,parameterTypes会把从Model的类加载器中解析出来的Class取出来,而不是脚本自己。 > model.addDependency(模型&addDependency.parameterTypes [0] .newInstance(DEP)) – Corrodias
@Corrodias:因此,这基本上意味着通过反射来访问该类别?它可能工作,但不幸的是我现在无法测试,因为代码在Jenkins的常规沙箱中运行,不允许使用这些方法,所以我必须等到它被管理员批准为止。 (也许在星期一) – user140547