现有公用方法的NoSuchMethodError

时间:2018-07-12 22:42:24

标签: java exception runtime

我在下面粘贴的代码中面临着一个非常神秘的java.lang.NoSuchMethodError。通过反射调用的相同方法按预期工作:

Widget a = getTextBoxWidget();
com.google.gwt.user.client.ui.UIObject uio = a; // Widget extends UIObject
for (java.lang.reflect.Method method : uio.getClass().getMethods()) {
    if (method.getName().equals("getElement")) {
        System.err.println("Method " + method.getName() + ":" + 
                           method.getDeclaringClass().getName());
        System.err.println("Modifier " + 
                           java.lang.reflect.Modifier.toString(method.getModifiers()));
        System.err.println("Parameter count: " + method.getParameterCount());
        System.err.println("Parameter types: " + Arrays.asList(method.getParameterTypes()));
        System.err.println("Return type: " + method.getReturnType());
        try {
            Object result = method.invoke(uio, new Object[0]);
            System.err.println("Invocation successful: " + result);
            Object result2 = method.invoke(uio, new Object[0]);
            System.err.println("Invocation successful2: " + result2);
        } catch (Exception e) {
            System.err.println("Failed to invoke getElement: " + e);
            e.printStackTrace(System.err);
        }
    }
}
// until here everything is good and it seems that 
// we can call getElement and get the result, but...
Object result3 = uio.getElement(); // line 470, here I get java.lang.NoSuchMethodError

输出:

Method getElement:com.google.gwt.user.client.ui.UIObject
Modifier public
Invocation successful: <result here>
Invocation successful2: <result here>
Parameter count: 0
Parameter types: []
Return type: class com.google.gwt.dom.client.Element

Stacktrace:

java.lang.NoSuchMethodError: com.google.gwt.user.client.ui.UIObject.getElement()Lcom/google/gwt/user/client/Element;
at com.pyx4j.widgets.client.ValueBoxBase.setAriaLabel(ValueBoxBase.java:470)

这可能是什么原因?
uio.getClass().getClassLoader()sun.misc.Launcher$AppClassLoader, id=151 method.getDeclaringClass().getClassLoader()相同,但ID相同。

-verbose:class运行会显示UIObject类,该类将从预期加载的位置加载。 UIObject.class中的主要版本为52,与运行时主要版本(1.8)相匹配

1 个答案:

答案 0 :(得分:3)

似乎在编译过程中和在运行时,代码实际上可能有所不同。

反射输出表明UIObject.getElement()方法的返回类型为com.google.gwt.dom.client.Element,但是JVM抱怨它想要com.google.gwt.user.client.Element。请注意,完全合格的类名中间的domuser子包中的差异。

如果这两种类型之间没有covariant relation(如前者扩展后者),则可能存在错误。由于第470行正在分配给Object,所以没有类型转换。如果在第470行中使用了实际的返回类型来声明ClassCastException,则可能会有result3

相关问题