which is the correct use of gwt-exporter for creating standalone javascript libraries?

125 views
Skip to first unread message

Alessio

unread,
May 19, 2014, 1:27:13 PM5/19/14
to gwtex...@googlegroups.com
Good morning,
I'm a noob in using gwt-exporter.
I've starting playing with this tool because I would like to wirte pure js libraries starting from Java, and then share them with my work team that only works with javascript.

Until now I've done the following:
- installed Java 8 + Eclipse 4.3.2. Kepler
- installed Google / GWT plugins under Eclipse
- downloaded the gwt-export jar

The test I've run is the following:
- I've created a new Web Application Project without sample code
- I've added a .gwt.xml file in the src directory, in the path corresponding to the main package of the project
- I've added an entry point class for a subpackage "lib" (Lib_EntryPoint.java)
- I've added a library class to be converted into js (CSV.java)
The result is contained in this archive: https://docs.google.com/uc?id=0B1XaMeHi9dz4WEcwdjZnWlJNMUk&export=download
If the link doesn't work, then try https://drive.google.com/file/d/0B1XaMeHi9dz4WEcwdjZnWlJNMUk/edit?usp=sharing
(then click on File -> Download)



While I compile the project in Eclipse (Google button -> GWT Compile Project...), the output I obtained until now is not what I really meant, so here are some questions, hoping that someone can give me a hint:

1 - I've seen that js code generated from the Java class CSV.java is located in the folder "war/module_name", not in a single js file as expected, but in different versions in several html files (some_MD5.cache.html).
Why isn't there a single file where my generated js is written?
Why the generated file is not in a js file, that can be included later by some other javascripts? How can I achieve this?

2 - Going straight to my goal, I would like to build modular libraries, and have a one-to-one correspondance between Java classes and js generated files, so that for example my CSV.java is translated into a CSV.js file containing only that class, and directly usable in a generic js context (browser, server, etc.).
Is there a known best-practice to do this? I've surfed the web a lot searching for tutorials / help, but I coulnd't find examples or articles describing how to afford my particular scenario.

3 - I've seen that my generated js packages / classes are a sub-member of the object $wnd, so that I have to call "new $wnd.com.example.codebase.lib.CSV()" instead of "new com.example.codebase.lib.CSV()".
Is there a way to tell the exporter that I want packages / classes callable in the second form?


Any help is greatly appreciated!
Alessio

Manuel Carrasco Moñino

unread,
May 20, 2014, 2:12:51 AM5/20/14
to gwtex...@googlegroups.com
On Mon, May 19, 2014 at 7:27 PM, Alessio <a.v...@gmail.com> wrote:
Good morning,
I'm a noob in using gwt-exporter.
I've starting playing with this tool because I would like to wirte pure js libraries starting from Java, and then share them with my work team that only works with javascript.

Until now I've done the following:
- installed Java 8 + Eclipse 4.3.2. Kepler
- installed Google / GWT plugins under Eclipse
- downloaded the gwt-export jar

The test I've run is the following:
- I've created a new Web Application Project without sample code
- I've added a .gwt.xml file in the src directory, in the path corresponding to the main package of the project
- I've added an entry point class for a subpackage "lib" (Lib_EntryPoint.java)
- I've added a library class to be converted into js (CSV.java)
The result is contained in this archive: https://docs.google.com/uc?id=0B1XaMeHi9dz4WEcwdjZnWlJNMUk&export=download
If the link doesn't work, then try https://drive.google.com/file/d/0B1XaMeHi9dz4WEcwdjZnWlJNMUk/edit?usp=sharing
(then click on File -> Download)



While I compile the project in Eclipse (Google button -> GWT Compile Project...), the output I obtained until now is not what I really meant, so here are some questions, hoping that someone can give me a hint:

1 - I've seen that js code generated from the Java class CSV.java is located in the folder "war/module_name", not in a single js file as expected, but in different versions in several html files (some_MD5.cache.html).
Why isn't there a single file where my generated js is written?
Why the generated file is not in a js file, that can be included later by some other javascripts? How can I achieve this?

That is the default output for GWT compiler, if you want pure .js files which could be deployed in any CDN simply change the linker at some point in your .gwt.xml file (preferably at the end) 

  <add-linker name="xsiframe"/>
or 
  <add-linker name="xs"/>
 

2 - Going straight to my goal, I would like to build modular libraries, and have a one-to-one correspondance between Java classes and js generated files, so that for example my CSV.java is translated into a CSV.js file containing only that class, and directly usable in a generic js context (browser, server, etc.).
Is there a known best-practice to do this? I've surfed the web a lot searching for tutorials / help, but I coulnd't find examples or articles describing how to afford my particular scenario.

GWT is not thought to have one class.java to one file.js correspondence because you would need a module (.gwt.xml) file and an entrypoint per class. This implies that any module would have common stuff in the js needed to gwt work like collections, dom code, etc.
What normally people does in GWT is have an entry-point and export your API with gwt-exporter, so as you export different parts of your code in logic parts. The way to split code in gwt is to use code-splitting which generates additional .js files which are loaded asynchronously when they are going to be used, but js coders do not have control on which files to load, they just inlcude the *.nocache.js file in their page.
 

3 - I've seen that my generated js packages / classes are a sub-member of the object $wnd, so that I have to call "new $wnd.com.example.codebase.lib.CSV()" instead of "new com.example.codebase.lib.CSV()".
Is there a way to tell the exporter that I want packages / classes callable in the second form?

Actually from the JS word you call your methods in the second way, see gwt-exporter documentation examples. $wnd represents in gwt the page window (since gwt is normally executed in a hidden iframe for isolation) , so any code in your .html does not need that variable

- Manolo
 


Any help is greatly appreciated!
Alessio

--
Has recibido este mensaje porque estás suscrito al grupo "gwtexporter" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a gwtexporter...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Alessio

unread,
May 20, 2014, 7:18:13 AM5/20/14
to gwtex...@googlegroups.com
Hello Manolo,
Thank you for great hints!

I'm still a bit confused, so I'll try to take a little bit more advantage from your experience :)

I'm trying to create JS libraries that could be used in a generic JS engine context, not in particular in a browser / httpclient context, but I still don't undertsand if there's a way to have my exported code in a single context-independant file.
The generated js files (I've added the "add-linker" directive, so now I got js instead of html) contain several times the definition of the exported classes / methods, and moreover they seem strictly connected with the fact that we are client side, since "window" and "document" object are the basis for the gwt common stuff, and the js file chosen will be loaded with "document.write".

Instead I would like:
- to have a unique generic definition of the exported source code (not several MD5.cache.js files with the exported classes defined several times)
- to have the code compliant also for a non-browser context (so without references to browser specific objects like "window" or "document"); for example I would like my code to be directly usable with engines like Rhino or Nashorn

Is this possible?

Thank you,
Alessio

Manuel Carrasco Moñino

unread,
May 20, 2014, 8:23:22 AM5/20/14
to gwtex...@googlegroups.com
On Tue, May 20, 2014 at 1:18 PM, Alessio <a.v...@gmail.com> wrote:
Hello Manolo,
Thank you for great hints!

I'm still a bit confused, so I'll try to take a little bit more advantage from your experience :)

I'm trying to create JS libraries that could be used in a generic JS engine context, not in particular in a browser / httpclient context, but I still don't undertsand if there's a way to have my exported code in a single context-independant file.
The generated js files (I've added the "add-linker" directive, so now I got js instead of html) contain several times the definition of the exported classes / methods, and moreover they seem strictly connected with the fact that we are client side, since "window" and "document" object are the basis for the gwt common stuff, and the js file chosen will be loaded with "document.write".

Instead I would like:
- to have a unique generic definition of the exported source code (not several MD5.cache.js files with the exported classes defined several times)

GWT produces different permutation per browser, so you have a bootstrap script: my_module.nocache.js which decides which MD5.cache.js to load, so all MD5 files have almost the same stuff but with specific tricks for that browser.

You can use the  <collapse-all-properties /> to generate one file which includes all browser flavours, it is little bigger than the biggest MD5.cache.js. 

Or you can define the browsers you want to support for only generating their stuff <set-property name="user.agent" value="safari,ie10,gecko1_8" />

You can also set the  <add-linker name="sc"/> to include all the stuff in one script (single script linker) 

 
- to have the code compliant also for a non-browser context (so without references to browser specific objects like "window" or "document"); for example I would like my code to be directly usable with engines like Rhino or Nashorn

In theory it is possible, but probably you have to use your own linker, and avoid using any GWT class with DOM specific stuff like Element, etc.

Think that the compiler translates java to js, but many times it copies directly java methods implemented in js, take a look to what GWT JSNI is.
Every JSNI method implementations should work but those using DOM 
 

Is this possible?

Thank you,
Alessio

Alessio

unread,
May 20, 2014, 2:23:00 PM5/20/14
to gwtex...@googlegroups.com
Hello Manolo,
Thank you again, I finally managed to compile everything in a single file using <collapse-all-properties /> and <add-linker name="sso"/> (setting name="sc" was giving me an "invalid linker name" error).

I've tried to run the generated code in a Rhino engine, but as expected exceptions are thrown because GWT generated code uses the "document" object to set up the library.

If I want to go on with my adventure, I guess I have no choice but writing my own linker, to avoid the use of browser generated objects, and have it running in a general client or server context.

Do you have any hint / link to tutorials for knowing more about writing a custom linker? I've checked some articles, but it seems that now the hard part has arrived :)

Thank you!
Alessio

Manuel Carrasco Moñino

unread,
May 21, 2014, 1:01:12 AM5/21/14
to gwtex...@googlegroups.com
On Tue, May 20, 2014 at 8:23 PM, Alessio <a.v...@gmail.com> wrote:
Hello Manolo,
Thank you again, I finally managed to compile everything in a single file using <collapse-all-properties /> and <add-linker name="sso"/> (setting name="sc" was giving me an "invalid linker name" error).

You'r right, I said that by memory and din't check.
 

I've tried to run the generated code in a Rhino engine, but as expected exceptions are thrown because GWT generated code uses the "document" object to set up the library.

If I want to go on with my adventure, I guess I have no choice but writing my own linker, to avoid the use of browser generated objects, and have it running in a general client or server context.

Do you have any hint / link to tutorials for knowing more about writing a custom linker? I've checked some articles, but it seems that now the hard part has arrived :)

You have to dive in projects generating JS for other devices, IIRC there is a gwt-couchdb generating map-reduce js to be run in server side they have a customized linker, also there is a project called gwt-chrome which have its own linker to produce chrome extensions, another linker is in the gwt-firefox-extension project.

Keep us updated with your progress

- Manolo
 

Thank you!
Alessio

Alessio

unread,
May 21, 2014, 6:19:24 PM5/21/14
to gwtex...@googlegroups.com
Hello Manolo,
Thank you very much again, I'm trying to reverse engineer couchdb-gwt now :)

I've tried to brutally put the custom linker in the couchdb-gwt (com.os.couchdbjs.linker.JsScriptLinker), that seems the one that should link the code targetting Rhino engine, but I had to modify an error in the code (com.google.gwt.dev.util.DefaultTextOutput.print() method does not accept a String[] as param, so I modified "out.print(result.getJavaScript());" to "for (String javascript : result.getJavaScript()) { out.print(javascript); }").
After that, a parsing error on the generated code just blocks me from using this linker.

It seems an unresolved problem in the linker source code (or maybe he was using a modified version of the com.google.gwt.dev.util.DefaultTextOutput class), but I don't know how to contact the author, since on the project page (https://code.google.com/p/couchdb-gwt/) there's no contact info but a partial address of the owner (v.mita...@gmail.com).
Do you know how to contact a google code project owner? Sorry but I'm a rookie also in this... :(

If I can't get this working I'll have to understand deeper what the linker does.

Of course I'll keep you informed if I succeed! It would be a great achievement for my team and it would increase our performance in coding on javascript server platforms!
Thank you,
Alessio

Reply all
Reply to author
Forward
0 new messages