我在下面粘贴的代码中面临着一个非常神秘的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)相匹配
答案 0 :(得分:3)
似乎在编译过程中和在运行时,代码实际上可能有所不同。
反射输出表明UIObject.getElement()
方法的返回类型为com.google.gwt.dom.client.Element
,但是JVM抱怨它想要com.google.gwt.user.client.Element
。请注意,完全合格的类名中间的dom
和user
子包中的差异。
如果这两种类型之间没有covariant relation(如前者扩展后者),则可能存在错误。由于第470行正在分配给Object
,所以没有类型转换。如果在第470行中使用了实际的返回类型来声明ClassCastException
,则可能会有result3
。