如何使用 Groovy 动态对象来调用需要具体类型的方法(不引用它们)
How to use Groovy dynamic objects to call methods requiring concrete types (without referencing them)
给定以下代码:
def model = readMavenPom file: 'pom.xml'
dep = [
groupId : "org.foo",
artifactId : "bar",
version : "1.0" ]
我想打电话给Model.addDependency
model.addDependency(dep)
这给出了错误
Caught: groovy.lang.MissingMethodException: No signature of method: org.apache.maven.model.Model.addDependency() is applicable for argument types: (java.util.LinkedHashMap) values: [[groupId:org.foo, artifactId:bar, version:1.0]]
现在可以做到
model.addDependency(dep as Dependency)
引用class时。它可以正常工作。本地。
不幸的是,我必须在 Jenkins 上执行它,我 运行 对此 issue。所以基本上,如果我引用 Dependency
class,我会 运行 进入一些 class 加载问题。建议使用 "dynamic typing".
所以可以在不引用 class 的情况下调用 addDependency
?
问题是加载模型 class(我们称之为 "A")的 classloader 与您引用时脚本尝试使用的加载器不同依赖项 class ("B")。因此,您可以使用 classloader-B 创建 Dependency-B,但是 Model-A 需要 Dependency-A。
我们可以使用反射来获取对 Dependency-A class 的引用,然后使用相同的 属性 映射创建它的实例,如下所示:
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是一个方法引用,反射风格。我们肯定知道只有一个同名的方法并且它只有一个参数,所以我们只需要第一个参数的 class 并调用 newInstance,它的工作方式与 "as" 关键字相同.
给定以下代码:
def model = readMavenPom file: 'pom.xml'
dep = [
groupId : "org.foo",
artifactId : "bar",
version : "1.0" ]
我想打电话给Model.addDependency
model.addDependency(dep)
这给出了错误
Caught: groovy.lang.MissingMethodException: No signature of method: org.apache.maven.model.Model.addDependency() is applicable for argument types: (java.util.LinkedHashMap) values: [[groupId:org.foo, artifactId:bar, version:1.0]]
现在可以做到
model.addDependency(dep as Dependency)
引用class时。它可以正常工作。本地。
不幸的是,我必须在 Jenkins 上执行它,我 运行 对此 issue。所以基本上,如果我引用 Dependency
class,我会 运行 进入一些 class 加载问题。建议使用 "dynamic typing".
所以可以在不引用 class 的情况下调用 addDependency
?
问题是加载模型 class(我们称之为 "A")的 classloader 与您引用时脚本尝试使用的加载器不同依赖项 class ("B")。因此,您可以使用 classloader-B 创建 Dependency-B,但是 Model-A 需要 Dependency-A。
我们可以使用反射来获取对 Dependency-A class 的引用,然后使用相同的 属性 映射创建它的实例,如下所示:
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是一个方法引用,反射风格。我们肯定知道只有一个同名的方法并且它只有一个参数,所以我们只需要第一个参数的 class 并调用 newInstance,它的工作方式与 "as" 关键字相同.