Problem with JsInterop

259 views
Skip to first unread message

Arnaud TOURNIER

unread,
Aug 27, 2016, 9:51:50 AM8/27/16
to GWT Contributors
Hi,

I am playing with js Promises and maybe there's a problem with JsInterop or i don't understand something.

When wrapping the promises with JsInterop, i come to define the Resolver interface which represents the resolving callback that is given when constructing a promise. In Javascript it is a function and not an object, so the interface has the @JsFunction annotation.

Here is the Resolver interface (inspired from the TypeScript definition of Promises...) :

@JsFunction
@FunctionalInterface
public interface Resolver<T>
{
void resolve( T value );
}

Since the Javascript "resolve" function can be called without parameters and also with a Promise instead of a value, i would like to make those versions available in the interface.

But the @JsFunction annotation prevents from having this :

@JsFunction
public interface Resolver<T>
{
void resolve();

void resolve( T value );

void resolve( Promise<T> value );
}

That's because it allows only one method in the annotated interface.

That is what i don't understand : AFAIK, the gwt compiler has to call the same function in the same way for the three declared methods (because of the semantic of the @JsFunction annotation), just changing the calling parameters. So i don't understand why is there the limitation of having only one method allowed in @JsFunction interfaces... If it would it would give even much power to JsInterop !

Could you please bring light to my misunderstanding ?

Thanks !

Arnaud

Colin Alworth

unread,
Aug 27, 2016, 10:13:38 AM8/27/16
to GWT Contributors
Part of the problem would come from figuring out how to call from JS back into Java - if you called resolve(null), was null a T or was null a Promise? And from JS, how could you typecheck to figure out whether to call the resolve_1(value) or resolve_2(promise)?

Its also possible in JS to call with too many arguments, and if you call with not enough, they get a null value, so we'll have a resolve_0() in there too - but if the wrong number of arguments are there, which do you invoke?

So, rather than JsInterop being a method lookup layer to translate to Java method call semantics, JsInterop uses JS semantics and lets you use them from Java. Just as you would write your resolve method in JS, you should write it in Java - take the object, and based on the value, decide what to do with it.

Now I realize that this doesn't directly apply to your case, since you want to do it the other way around - pass an object implemented in JS into Java and interact with it there, but JsInterop provides functionality to work in both directions, and I'm not certain how you could tell JsInterop that you will never implement an interface in Java, or if that is functionality that we want. Instead, you could have a single method resolve(Object), and let JS sort it out, whether you call it with null, a value, or another promise.

(Disclaimer, I'm not a JsInterop expect, but I'm trying to learn quickly.)

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/15705e1b-c1cf-46ec-add7-96d2b787f8fe%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Arnaud TOURNIER

unread,
Aug 27, 2016, 11:56:07 AM8/27/16
to GWT Contributors

Hi Collin,
Thanks for your answer, I understand now, I was only focusing on my problem and forgot the JS to Java way. As you say, something cool would be to be able to say to JsInterop that the interface will only be used in the Java to JS way...
Thanks!


You received this message because you are subscribed to a topic in the Google Groups "GWT Contributors" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-web-toolkit-contributors/pNmyrzkfPWo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CADcXZMxQAj-TExK50id9AVKB36mWv8JnAW5f%2BK0Zg4%3D9SOi74A%40mail.gmail.com.

Paul Stockley

unread,
Aug 30, 2016, 10:06:15 AM8/30/16
to GWT Contributors
If you are passing  Resolver<T> into some function. You could instead create 3 Resolver interfaces and then overload the function so that it took each of the resolver interfaces.

Arnaud TOURNIER

unread,
Aug 30, 2016, 10:13:57 AM8/30/16
to GWT Contributors

Oh thanks! I'll try that.
Once I think we need to merge our work on those topics...
Thanks!


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

Goktug Gokdogan

unread,
Sep 1, 2016, 11:28:45 PM9/1/16
to google-web-toolkit-contributors
The limitation around @JsFunction is basically driven from the limitations of being a function. I think there was an earlier discussion in the contibutor list where we explained this in more detail.

Being said that, you can handle some overloading in JsFunction interfaces via defender methods marked with @JsOverlay that are delegating to a main method. Something like:


@JsFunction
public interface Resolver<T> {

void resolve(Object value);

        @JsOverlay
default void resolve() { resolve(null); }
        @JsOverlay
default void resolve(T value) { resolve(value); }
        @JsOverlay
default void resolve(Promise<T> value) { resolve(value); }
}

Let's us know before it is too late if you hit any bugs around this :)


To unsubscribe from this group and all its topics, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.

Arnaud TOURNIER

unread,
Sep 2, 2016, 1:08:26 AM9/2/16
to google-web-toolkit-contributors
Thanks a lot for your answer.

I tried the solution with defender methods earlier but it did not work, as far as i remember the compiler refused @JsOverlay defender methods on the JsFunction. The @JsFunction documentation says that : "A JsFunction interface cannot have defender methods."
I will try again in this direction and let you know if i find a bug.

Thanks
Arnaud

To unsubscribe from this group and all its topics, send an email to google-web-toolkit-co...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "GWT Contributors" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-web-toolkit-contributors/pNmyrzkfPWo/unsubscribe.

Goktug Gokdogan

unread,
Sep 2, 2016, 1:21:12 PM9/2/16
to google-web-toolkit-contributors
That is added relatively recent.
And thanks for pointing the documentation issue; add a issue to review all before the final release.

On Thu, Sep 1, 2016 at 10:08 PM, Arnaud TOURNIER <lte...@gmail.com> wrote:
Thanks a lot for your answer.

I tried the solution with defender methods earlier but it did not work, as far as i remember the compiler refused @JsOverlay defender methods on the JsFunction. The @JsFunction documentation says that : "A JsFunction interface cannot have defender methods."
I will try again in this direction and let you know if i find a bug.

Thanks
Arnaud

To unsubscribe from this group and all its topics, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

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

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
Reply all
Reply to author
Forward
0 new messages