访问getter时带有签名的Groovy MissingMethodException和继承时的NoSuchMethodError

时间:2016-08-04 09:06:39

标签: groovy dependency-management

你能解释一下为什么有时groovy在java代码调用getter时会抛出MissingMethodException并且有一个同名的属性吗?

次要问题:

你能解释为什么我的第一个解决办法对第二个用例无效吗?

以下脚本有效,因为我添加了 methodMissing

#!/usr/bin/env groovy    
@Grapes([
    @Grab(group='org.jvnet.hudson', module='xstream', version='1.4.7-jenkins-1'),
])
def a

println 'xstream'
com.thoughtworks.xstream.XStream s = new com.thoughtworks.xstream.XStream()
println s
def reg1 = s.converterRegistry
println "using property: $reg1"

com.thoughtworks.xstream.XStream.metaClass.methodMissing = { String name, def args ->
    println "missing $name"
    if (name=="getConverterRegistry") {
        return delegate.converterRegistry
    }
}

def reg2 = s.getConverterRegistry()
println "using getter  : $reg2"

println "ok"

此脚本打印:

com.thoughtworks.xstream.XStream@6c45ee6e
using property: com.thoughtworks.xstream.XStream$2@2e8e8225
missing getConverterRegistry
using getter  : com.thoughtworks.xstream.XStream$2@2e8e8225
ok

方法getConverterRegistry存在于XStream中但如果您注释掉方法,则会得到: groovy.lang.MissingMethodException:没有方法签名:com.thoughtworks.xstream.XStream.getConverterRegistry()适用于参数类型:()值:[]         在TestXStream.run(TestXStream.groovy:24)

我在做这项工作时充满了希望(虽然它并不漂亮)但我的问题仍在继续,因为我的代码实际上是使用jenkins库而且以下代码不起作用:

#!/usr/bin/env groovy

import hudson.util.XStream2
import com.thoughtworks.xstream.XStream

@Grapes([
    @Grab(group='org.jvnet.hudson', module='xstream', version='1.4.7-jenkins-1'),
    @Grab(group='org.jenkins-ci.main', module='jenkins-core', version='1.642.3', transitive=false),
])
def a

XStream.metaClass.methodMissing = { String name, def args ->
    println "missing $name for XStream"
    if (name=="getConverterRegistry") {
        return delegate.converterRegistry
    }
}

def reg2 = new XStream().getConverterRegistry()
println reg2

XStream2.metaClass.methodMissing = { String name, def args ->
    println "missing $name for XStream2"
    if (name=="getConverterRegistry") {
        return delegate.converterRegistry
    }
}

println 'xstream2'
XStream2 s2 = new XStream2() // internal call to this.getConverterRegistry()
println "ok"

输出:

missing getConverterRegistry for XStream
com.thoughtworks.xstream.XStream$2@c2db68f
xstream2
Caught: java.lang.NoSuchMethodError: hudson.util.XStream2.getConverterRegistry()Lcom/thoughtworks/xstream/converters/ConverterRegistry;
java.lang.NoSuchMethodError: hudson.util.XStream2.getConverterRegistry()Lcom/thoughtworks/xstream/converters/ConverterRegistry;
        at hudson.util.XStream2.wrapMapper(XStream2.java:188)
        at com.thoughtworks.xstream.XStream.buildMapper(XStream.java:610)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:568)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:496)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:465)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:411)
        at com.thoughtworks.xstream.XStream.<init>(XStream.java:350)
        at hudson.util.XStream2.<init>(XStream2.java:89)
        at TestXStream2.run(TestXStream2.groovy:33)

类XStream包含属性converterRegistry及其getter。 XStream2扩展了XStream,并继承了getter。

请注意,当我从eclipse运行它时它工作正常并且在使用CLI时我有这个问题;可能是因为eclipse会比编译器更改这段代码。

任何线索?

1 个答案:

答案 0 :(得分:0)

我通过切换回主要启动器的普通Java来解决这个问题。 我使用相同的超级罐作为依赖,就像我使用groovy和葡萄一样。

我不知道它与groovy或者葡萄有什么关系(我怀疑是groovy)但我在它周围工作。