Comment by a.revolution.ultra.blue:
One hack I was using to get modules to "speak through compilations" was
using Ray's exporter. Basically, common functions like custom dialogs that
cover the screen... If I want them to look nice, but be accessible before
I ever access Widget code, I use public static class methods like
note(String txt), ask(String question, AsyncCallback response, String ...
answers). These methods aren't even in the same package as the code that
implements them; they just tunnel through a "JS API"
$wnd.parent.MyExportedAPI. The root API module puts a JS object
MyExportedAPI on it's $wnd, then it loads the "dll" nocache.js files, which
implement things like note() and ask(), adding them to
MyExportedAPI.Dialog.ask()
Finally, each osgi iframe has .nocache.js modules that never access the
packages which implement the UI stuff, only static methods that tunnel to
$wnd.parent.ME_API {or $wnd.parent.parent...ME_API}. Biggest issue was
context. All callbacks from an osgi child of the root must send along it's
window variables {NOT $wnd}, and map all the parameters in and out of JSNI.
Think:
public static native void getFeeling(AsyncCallback<String> callback)
/*-{
top.MyExportedAPI.ask("How are you", ["Good","Great","Alright"], {
wind: window
, callback : [email protected]::onSuccess(Ljava/lang/String;)
, err : [email protected]::onFailure(Ljava/lang/Throwable;)
});
}-*/;
then, to actually perform the callback, in JSNI,
x.callback.call(x.wind, 'Great')
PROBLEMS {only some of them}:
* Memory leaks; adding gwt workspace iframe.contentWindow to every tunneled
call could get REAL messy.
* Hand coded; it works, but there's piles and piles of boilerplate code;
external public static access, a to JSNI bridge method, a from JSNI bridge,
and finally, an implementation method. Don't forget @Export boilerplate
too!
* Tracing errors becomes nearly impossible. Had to make a special,
ForeignException so different frames could throw an error and call an
asyncCallback.onFailure without ClassCastException.
* Accessing osgi subframes {/ls, /dl} without being a child of the root
frame = not possible. Power users like to skip straight to the url w/
content, sans fancy multiple-module downloads.
* "Dlls" came in .cache.html, so they didn't block downloads of other code,
which I thought was an advantage, but with heavy caching situations, weird
page reload bugs happened when the root api changed, but the children did
not.
* Proxied calls were slllllow
* Event.addNativeEventListener does not work through iframes
* Compile times through the roof!!
* A giant wad of atrocities I've tried to block out.
Trust me, the amount of extra dancing and working you will have to do
for "dll osgi-like modules" will cost you more time than money can
replace. And what Ray mentioned before about RPC is that your obfuscated
Java objects CANNOT sanely be made translatable unless you RPC
encode/decode when tunneling to the root MyExportedAPI. This would mean an
encode/decode pair of overhead methods for every paramete or returned
object that's not a primitive or JSO.
I did all this before runAsync and GWT2.0 was compatible with Appengine,
and I TOTALLY ABANDONDED THIS METHOD. It hurt too much to implement.
Maybe if I was a generator wizard like Ray it wouldn't be so bad, but at
least my package segregation methods made the "root API" modules
transferable to runAsync without worry of external dependancy.
...If you feel like you wasted time reading these run on sentences of mine,
do yourself a favor, AND SPARE YOUR CODING TIME, COMPILING TIME AND
EXECUTION SPEED: *Monolithic* *Compile* *Is* *The* *Only* _efficient_
*Way* *To* *Obfuscate*, *Split* *And* *Link* *Independent* *Modules*. Any
other way means a translation layer and jumping through lots of unnecessary
hoops!
For more information:
http://code.google.com/p/google-web-toolkit/wiki/CodeSplitting
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---