如何使用Groovy动态对象调用需要具体类型的方法(不需要引用它们) [英] How to use Groovy dynamic objects to call methods requiring concrete types (without referencing them)

查看:429
本文介绍了如何使用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()适用于参数类型:(java.util.LinkedHashMap)values:[[groupId:org.foo,artifactId:bar,version:1.0]]

现在可以做

$ p $ model.addDependency(dep作为依赖)

引用类时。它工作没有问题。本地。



不幸的是,我必须在Jenkins上执行这个操作,并且我正在运行 issue 。所以基本上,如果我引用 Dependency 类,我会遇到一些类加载问题。建议使用动态类型。



因此,可以在不引用该类的情况下调用 addDependency

解决方案

问题在于,加载Model类的类加载器(我们称之为A)与之不一样如脚本尝试在引用依赖类(B)时使用。所以你可以用你的classloader-B创建一个Dependency-B,但是一个Model-A需要一个Dependency-A。

我们可以使用reflection来获得对依赖 - 一个类,然后使用相同的属性映射创建它的一个实例,如下所示:

  def model = readMavenPom file: 'pom.xml'
dep = [
groupId:org.foo,
artifactId:bar,
版本:1.0]
模型。 addDependency(model。& addDependency.parameterTypes [0] .n ewInstance(dep))

Groovy和& addDependency是一种方法引用,反射风格。我们肯定知道只有一个名称的方法,它只有一个参数,所以我们只需要第一个参数的类并调用newInstance,它与as关键字具有相同的方式。


Given the following code:

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

I would like to call Model.addDependency

model.addDependency(dep)

This gives the error

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]]

Now it is possible to do

model.addDependency(dep as Dependency)

When referencing the class. And it works without problems. locally.

Unfortunately, I have to execute that on Jenkins, and I am running into this issue. So basically, if I reference the Dependency class, I running into some class loading issues. There is a recommendation to use "dynamic typing".

So it is possible to call addDependency without referencing that class?

解决方案

The problem is that the classloader that loaded the Model class (let's call it "A") is not the same one as the script tries to use when you refer to the Dependency class ("B"). So you can create a Dependency-B with your classloader-B, but a Model-A demands a Dependency-A.

We can use reflection to get a reference to the Dependency-A class, then create an instance of it using the same property map, like so:

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

In Groovy, &addDependency is a method reference, reflection style. We know for certain that there's only one method by that name and it has only one parameter, so we just take the first parameter's class and call newInstance, which works the same way as the "as" keyword would have.

这篇关于如何使用Groovy动态对象调用需要具体类型的方法(不需要引用它们)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆