1

I am trying to access a Java object that currently is in a property of a JavaScriptObject but the conversion fails. Here is what I do:

public static native MyJavaObject getMyObject(JavaScriptObject obj) /*-{
  return obj['myProp'];
}-*/;

obj.myProp is a Java object that is created by a Java constructor (which is visible in Javascript since it is exported). The result when I run the code above is a java.lang.ClassCastException in development mode.

However, if do like below and access the secret property g it works! It seems that gwt does not remove the wrapper when it converts the return value.

public static native MyJavaObject getMyObject(JavaScriptObject obj) /*-{
  return obj['myProp'].g;
}-*/;

The code above works but it is not a solution since it uses implementation details in gwt. What am I doing wrong?

Thanks /Johan

Some new conclusions found by testing:

It seems the problems depend on objects exported by gwt-exporter are not converted as I expected in native code.

  • Exported objects are wrapped and the original object is stored in a property named g.
  • Since GWT does not know of this it can not retrieve the original object from a wrapped exported object.
  • When going through exported interfaces wrapping and unwrapping is automatic.
  • The exception to this seems to be when executing code dealing with exported object in native methods. Native methods behave differently than code defined as javascript in that they do not seem to handle export unwrapping. This was found by trying to call an exported method with a exported object as parameter. It failed from native code but doing the same from ordinary javascript worked.

Can someone with knowledge of the implementation details in gwt-exporter confirm my assumptions?

2
  • Do MyJavaObject extends JavaScriptObject ? If it don't, try to do so. Commented Feb 29, 2012 at 16:58
  • Either don't try to do so, or make sure to refer to the property using proper JSNI notation, see code.google.com/webtoolkit/doc/latest/… Commented Feb 29, 2012 at 20:54

1 Answer 1

1

Now I have found a way to do this. My conclusion that native code and ordinary JavaScript was treated differently depended on that exported classes were not in the current scope and needed to be prepended by $wnd.

Here is how I converted my JavaScriptObject to the the exported class Icon. It is a bit awkward but it works and is not depending on implementation details.

public class ConvertUtils implements Exportable {

    private static Icon icon_;

    public static Icon icon(JavaScriptObject obj) {
        icon_ = null;
        setIconNative(obj);
        return icon_;
    }

    private static native void setIconNative(JavaScriptObject obj) /*-{
        $wnd.ravegeo.ConvertUtils.setIcon(obj);
    }-*/;

    @Export
    public static void setIcon(Icon icon) { 
        icon_ = icon; 
    }
}

The trick is to transfer the object through an exported method where it gets unwrapped (the setIcon method).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.