I'm facing a very mysterious java.lang.NoSuchMethodError
in the code pasted below. The same method, called through reflection, works as expected:
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
Output:
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)
What can the possible cause for this?
uio.getClass().getClassLoader()
is sun.misc.Launcher$AppClassLoader, id=151
method.getDeclaringClass().getClassLoader()
is the same, with the same id.
Running with -verbose:class
shows the UIObject
class loaded from wherever it is expected to be loaded. The major version inside UIObject.class
is 52, which matches the runtime major version (1.8)
It appears that the code actually might be different during the compilation and in runtime.
Reflection output suggests that UIObject.getElement()
method return type is com.google.gwt.dom.client.Element
however the JVM complains that it wants com.google.gwt.user.client.Element
. Notice difference in the dom
and user
sub-packages in the middle of the fully qualified class name.
If there is no covariant relation between these two types, as in former extends latter, there might be an error. There is no type casting since line 470 is assigning to an Object
. Maybe there will be a ClassCastException
if an actual return type is used to declare result3
in line 470.