GWT2.8 JsInterop Java->JS

977 views
Skip to first unread message

Alex W

unread,
May 15, 2015, 1:51:38 AM5/15/15
to google-we...@googlegroups.com
We are usingJSInterop in GWT2.8. In one of our RPCs we have some code like this that passes our java object to JS:
onSuccess(List<MyObject> objs) { 
   for (MyObject obj: objs) {
     jsCode.printObj("We can't see the obj's properties, only:" + obj);
  }
}
The definition of jsCode looks like this:
ns.printObj = function(obj) {
   console.log(JSON.stringify(obj));
}
In the console we get back:
We can't see the obj's properties, only:our.ns.type.MyObject@16

The value object has been annotated as @JsType. Anything else we need to do?

Alberto Mancini

unread,
May 15, 2015, 2:47:39 AM5/15/15
to google-we...@googlegroups.com
Hi,
you are converting obj to a string before calling printObj:  "We can't see the obj's properties, only:" + obj 

Hope this helps.
   Alberto. 


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-tool...@googlegroups.com.
To post to this group, send email to google-we...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

Alex W

unread,
May 15, 2015, 2:57:24 AM5/15/15
to google-we...@googlegroups.com
Wouldn't the object have a bunch of JSON properties then?

Alberto Mancini

unread,
May 15, 2015, 3:09:50 AM5/15/15
to google-we...@googlegroups.com
the object has properties but when you concatenate a string with your object in the line
"We can't see the obj's properties, only:" + obj  
you are essentially converting obj to a string through obj.toString() so your 
native method does not receives the object obj but a string.

try this passing just obj to printObj.

A.
 

--

Alex W

unread,
May 15, 2015, 3:54:32 AM5/15/15
to google-we...@googlegroups.com
I tried that, it gave me the same result, but your post gave me an idea. I set printObj up to assign a variable with it's data, so the last element in the list would get it.

Inside
ns.printObj = function(data) {
   ns.foo = data;
}

Then I typed ns.foo into chrome's dev console so I could introspect the object that way. It turns out that the data is there, but it's all mangled with funny symbols like
kRg_g$ {  mySymbol_1_g$  } etc. Can anyone on the GWT team weigh in and tell me how to unmangle it, such that I can write my views in JS and my model/controller in java?

On a side note, it would be really nice if there was a nice no-brainer way of serializing/deserializing between JSON and Java Objects exposed to gwt users. This has always been a huge feature hole in gwt imo.

Thanks
Alex

Colin Alworth

unread,
May 18, 2015, 9:03:52 AM5/18/15
to google-we...@googlegroups.com
The '_1_g$' indicates you are in super dev mode - does it work correctly when fully compiled to JS (draft or no)? I saw a problem in this area a few weeks ago.

Also, can you post the full definition for MyObject?

I agree with Alberto though, your printObj doesn't make any sense as is - it is calling the java toString() method on the object rather than serializing to JSON, or do you expect MyObject.toString() to return a json string?

Alex W

unread,
May 19, 2015, 1:11:04 AM5/19/15
to google-we...@googlegroups.com
The '_1_g$' indicates you are in super dev mode - does it work correctly when fully compiled to JS (draft or no)? I saw a problem in this area a few weeks ago.

No it doesn't work when it's fully compiled to JS either.

Also, can you post the full definition for MyObject?


class MyObject {
    private String str1;
    private String str2;
    private boolean b1;
    private boolean b2;
    private boolean b3;
    private boolean b4;
    private boolean b5;
    private boolean b6;
    private int size;
    private String str3;
    private Boolean b7;
    private String str4;
    private int numb1;
    private long uid;
    private Boolean b7;
    private List<MyOtherObject> objs;

}

I agree with Alberto though, your printObj doesn't make any sense as is - it is calling the java toString() method on the object rather than serializing to JSON, or do you expect MyObject.toString() to return a json string?

I thought JSON.stringify(...) would stringify the (assumed) JSON object. I'm not really sure what's going on under the hood, but I don't really understand why/how it doesn't.

Colin Alworth

unread,
May 19, 2015, 10:18:41 AM5/19/15
to google-we...@googlegroups.com
JSON.stringify will try to serialize the js objects to a json string as best it can (ignoring cycles, and non-json data like methods).

At the risk of sounding snarky, you know that class won't work in JsInterop, right? For a start, its missing its @JsType! ;)

Next, some of these fields can't cleanly be passed between Java and JS - for example JS has no long type (will truncate to double precision, GWT emulates long), and a Java List<?> needs to be a type that exists in JS (either JsArray, or some jsinterop-annotated type that maps to what JS understands). This I'm less sure about, but at least historically boxed types like Boolean were never supported - the primitive type boolean has to be used instead.

Here's a very quick sanity check that I wrote to verify that this is working more or less as expected:
public class SampleEntryPoint implements EntryPoint {
  public void onModuleLoad() {
    MyData data = new MyData("Colin", 123);
    Window.alert(stringify(data));
  }

  public static native String stringify(Object obj) /*-{
    return $wnd.JSON.stringify(obj);
  }-*/;

  @JsType
  public static class MyData {
    public String name;
    public int age;
    public MyData(String name, int age) {
      this.name = name;
      this.age = age;
    }
  }
}

On startup this does indeed output {"name":"Colin","age":123}, though if you remove the @JsType annotation, it just outputs {} since GWT doesnt see any code using the fields, so it optimizes them out.

Live code:

This is however using a version of GWT 2.8 that is a few weeks old, I'll update later today and reverify.

--
You received this message because you are subscribed to a topic in the Google Groups "Google Web Toolkit" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-web-toolkit/ZCayeP1c5c0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-web-tool...@googlegroups.com.

Alex W

unread,
May 19, 2015, 9:31:18 PM5/19/15
to google-we...@googlegroups.com
It uses @JsType @JSExport and also implements Serializable. I already mentioned I was using those so I didn't put that in when I sanitized the code since we are not allowed to pastie actual work code. As a user in js, I would expect that all those types would have js analogs in js under their respective java.lang namespace. There are various Big Integer js libraries on github for example.

Looking at Ray Cromwell's slides I noticed there is a (vapour) reference to a Js.js(...) class that might do what I want. Apparently, it doesn't exist. Oops. At the risk of sounding snarky, GWT is a poorly run project, consistently overpromising and underdelivering.

Colin Alworth

unread,
May 19, 2015, 9:59:33 PM5/19/15
to google-we...@googlegroups.com
I'm sorry you haven't gotten this working, but posting incomplete examples makes it hard to help. This is still considered an experimental feature, though it is used in production both inside of Google and outside. 

Js.js is a proposed new JSNI, and is not required to do anything - the goal is to replace jsni/jsos entirely, and after JsInterop is complete and finalized, jsni may follow jsos out the door with something like Js.js. If memory serves, Js.js was implemented with a generator that simply created JSNI methods, but again, you don't need it.

Did you try my example? As I said, it does seem to work, and while your incomplete example may not be working yet, without knowing what you are trying, that doesn't mean GWT is the problem.

With regard to analogs for array, etc, there are a lot of basic objects that have to be implemented. Once the annotations and code generation is finalized, a so-called 'elemental 2.0' is planned, where interfaces will be generated based on JS and browser specs. 

in the interim, in the same way that JSNI can still let JS code live in a GWT/Java project, JSOs can still be used - JsArray is a legit way to reference js collections. Even with JsInterop, from what I understand between JS and Java, the upcoming JsInterop+elemental types won't be able implement java.util collection interfaces anyway, at least not without language level support for them directly. Not to say that this isn't planned, but that without it, any existing analogs will be as weak as JsArray itself, a existing, perfectly capable class.

--
Reply all
Reply to author
Forward
0 new messages