Using GWT libraries from J2CL

599 views
Skip to first unread message

Anders Forsell

unread,
May 31, 2017, 4:29:49 PM5/31/17
to GWT Contributors
Hello,

From the small examples of J2CL examples I have seen, the Java classes have been annotated with @JsType.
I understand that all Java code will be transpiled to ES6 JS classes with J2CL but can you refer/use other Java classes/libraries without adding specific annotations?

More concretely, if I have a GWT/Java library will I be able to use that library with J2CL without modifying the source of it? 

Thanks,

Anders

Goktug Gokdogan

unread,
May 31, 2017, 4:43:23 PM5/31/17
to google-web-toolkit-contributors
J2CL doesn't require @JsType; JsType serves same purpose as in GWT.

The likely steps required to make GWT library work with J2CL (future-proofing) already described in multiple talks earlier but briefly; no JSNI/JSO, no GWT.create, no generators and no com.google.gwt.* references. This applies recursively to the library's deps as well.

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/3193454b-b4c7-428b-8a19-3e730601868f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Anders Forsell

unread,
May 31, 2017, 5:24:17 PM5/31/17
to GWT Contributors
Ok, that sounds great!

Frank Hossfeld

unread,
Jun 1, 2017, 6:59:02 AM6/1/17
to GWT Contributors
I did not see any J2CL examples. Would be nice to know, how to replace the Entrypoint ...

Thomas Broyer

unread,
Jun 1, 2017, 7:22:26 AM6/1/17
to GWT Contributors
I believe j2cl is currently used to produce libraries only (that are then consumed by JS code and passed through the Closure Compiler to produce applications)
If j2cl doesn't have an equivalent already, I believe GWT 3 will still have EntryPoint with some "glue code" to make it run on load of the script.

Lars

unread,
Jun 1, 2017, 1:42:22 PM6/1/17
to GWT Contributors
In the GwtCon keynote 2016 it looks like a Main method (without parameters) in a Main class ... but I guess most of this is experimental ...

Anders Forsell

unread,
Jun 2, 2017, 6:37:44 AM6/2/17
to GWT Contributors
I have asked this before but I am still looking for an alternative to the GWT SimpleEventBus which will work with J2CL.

Would a library using annotation processsor like https://github.com/greenrobot/EventBus be possible to use? 

Anders


On Wednesday, May 31, 2017 at 10:43:23 PM UTC+2, Goktug Gokdogan wrote:

Thomas Broyer

unread,
Jun 2, 2017, 8:38:57 AM6/2/17
to GWT Contributors


On Friday, June 2, 2017 at 12:37:44 PM UTC+2, Anders Forsell wrote:
I have asked this before but I am still looking for an alternative to the GWT SimpleEventBus which will work with J2CL.

What's wrong with SimpleEventBus?

Anders Forsell

unread,
Jun 2, 2017, 9:31:18 AM6/2/17
to GWT Contributors
It's a com.google.gwt reference and in addition I am using it with https://github.com/google/gwteventbinder which relies on GWT.create

A solution with APT would be nicer.

Anders

Thomas Broyer

unread,
Jun 2, 2017, 1:10:24 PM6/2/17
to GWT Contributors
GWT 3 will likely still have SimpleEventBus (and it would compile with j2cl without change).

And gwteventbinder could quite easily be ported to an annotation processor.

Anders Forsell

unread,
Jun 2, 2017, 2:47:38 PM6/2/17
to GWT Contributors
Yes, I'm just trying to move away from all GWT dependencies and hoping that once J2CL is open-sourced I'll transition to it without having to wait for GWT3.

Thomas Broyer

unread,
Jun 4, 2017, 5:57:50 AM6/4/17
to GWT Contributors
Fwiw, here's a proof-of-concept annotation processor for gwteventbinder: https://gist.github.com/tbroyer/420004d02e905ba7ce9489d24d3bae72 (uses auto-service, auto-common, and JavaPoet)
It'll generate an EventBinder_Xxx class implementing EventBinder<Xxx> for any class Xxx with methods annotated with @EventHandler, so you can replace things like:
  interface MyEventBinder extends EventBinder<Xxx> {}
  private static final MyEventBinder eventBinder = GWT.create(MyEventBinder.class);
with
  private static final EventBinder<Xxx> eventBinder = new EventBinder_Xxx();

With a small modification to EventBinder (adding an inherited annotation), one could write an annotation processor that's fully backwards-compatible with the current approach. The GWT generator could be changed to simply return the class generated by the annotation processor as a migration step before you replace the GWT.create() with an explicit "new", something like:
  interface MyEventBinder extends EventBinder<Xxx> {}
  private static final MyEventBinder eventBinder = new Xxx_MyEventBinderImpl();

Note that the annotation processor linked above does absolutely no error handling and assumes the annotation is used "correctly" (one big difference of annotation processors is that they're invoked even if the code wouldn't compile, e.g. applying the annotation to a type whereas it only targets methods, or if the value of the annotation properties don't have the correct type, such as @EventHandler(42); with a GWT generator, those errors would be caught earlier in the process so the generator is immune to them).

Anders Forsell

unread,
Jun 5, 2017, 3:04:26 AM6/5/17
to GWT Contributors
LGTM!

Thomas Broyer

unread,
Jun 5, 2017, 7:22:07 AM6/5/17
to GWT Contributors


On Sunday, June 4, 2017 at 11:57:50 AM UTC+2, Thomas Broyer wrote:
With a small modification to EventBinder (adding an inherited annotation), one could write an annotation processor that's fully backwards-compatible with the current approach. The GWT generator could be changed to simply return the class generated by the annotation processor as a migration step before you replace the GWT.create() with an explicit "new", something like:
  interface MyEventBinder extends EventBinder<Xxx> {}
  private static final MyEventBinder eventBinder = new Xxx_MyEventBinderImpl();

Actually, inherited annotations don't trigger annotation processors when a subclass/subinterface is compiled :-(
Adding an annotation to the EventBinder subinterface would work though:
  @GenerateEventBinder interface MyEventBinder extends EventBinder<Xxx> {}
  private static final MyEventBinder eventBinder = new Xxx_MyEventBinderImpl();
But if you have to modify your code anyway I'm not sure this is worth it; the linked PoC processor using only @EventHandler might be enough then. There could theoretically be some cases where it would be a more involved change (things like not having @EventHandler methods in the class itself, but only on the superclass, where you'd have to use the EventBinder for the superclass; and/or inheriting @EventHandler defender methods from interfaces, where you'd then have several EventBinder to deal with), and it might possibly break some edge cases (such as an @EventHandler method in a generic superclass where the type arguments are used in the event argument), but I believe in most cases that should Just Work™.
 
(one big difference of annotation processors is that they're invoked even if the code wouldn't compile, e.g. applying the annotation to a type whereas it only targets methods, or if the value of the annotation properties don't have the correct type, such as @EventHandler(42); with a GWT generator, those errors would be caught earlier in the process so the generator is immune to them).

Forget that, this is plain wrong (at least with a recent Java 8 JDK), the generator is only called if the annotation is correctly applied.
It might have been the case with older versions of javac, or possibly when looking at other things than the ones the annotation processor has been asked to process; I'd swear I've seen cases where a processor would be invoked and had to check for some annotation usage because the compiler hadn't checked them yet (and thus had to ignore them to let the compiler do its job), couldn't reproduce it though.
Reply all
Reply to author
Forward
0 new messages