NoSuchMethodError for existing public method

khachik :

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)

Karol Dowbecki :

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=97841&siteId=1