Ok, I see where you're going, and I've been there.... A few times.
No, seperate root entry points have completely separate obfuscation
patterns, and will never share java objects. You CAN do it if you're
willing to collapse down to JSNI on every transaction, but this can be
costly and inefficient.
There are many roads open to you, and I personally recommend runAsync
() as it's the new, polished, officially supported method to make
monolithic apps WITHOUT using multiple frames. I've made two seperate
modules that are designed to communicate through iframes and shared
JSNI objects. In one, I extended onModuleLoad to use a communicator
interface, which accepts and sends JSNI objects using native methods
that rip out the javascript function from java mehtods, store them in
a namespace in the $wnd variables, so any two xModules with the same
global namespace string "hook up" the javascript objects in a very
dirty, hackish manner. It worked, but it is a REAL pain to debug
because "some" browsers don't like to communicate through iframes like
others. It also broke Opera and spent more time compiling the same
base code twice per iteration than I like to remember. The key of
this method is to use static JSNI namespacing to create a common int,
double and String "interfacing" {but with JSNI, no interfaces are
used. I just mean both sides of the iframe do stuff like {S:
2,S0:"Str1",S1:"Str2",I:1,I0:123}, and they just "know" how to access
the data}. NO JAVA OBJECTS ARE TRANSLATABLE, so don't use them
without converting through JSON.
http://www.aiyx.info/xSrc.html#xSource/xBook.xFacets.client.xCommunicator.java
http://www.aiyx.info/xSrc.html#xSource/xBook.logickmal.client.xRNA.java
http://www.aiyx.info/xSrc.html#xSource/xBook.xModulus.client.xModule.java
http://www.aiyx.info/xSrc.html#xSource/xBook.logickmal.client.xDNA.java
http://www.aiyx.info/xSrc.html#xSource/xBook.logickmal.client.xLocus.java
A new method I used to communicate through frames was to use GWT
Exporter to create global JSNI copies of Java object prototypes {also
using static namespacing}, and rather than hook up parentRx(childTx())
<- js -> childRx(parentTx()) links, I export all the root tasks into
the root, parent iframe, and then use native methods to find the root
gwt window, and send primitive data through static native functions to
get some cross frame communication going. This method is still buggy
and kind of ill because it has to store a reference to the modules
hidden iframe "scope" window, so ripped out java callbacks
{AsyncCallbacks} from the child window need to send the native window
{NOT $wnd} for context so the parent can wrap functions with stuff
like:
void xDo(JSO task,String x)/*-{
task.job.call(task.wnd, x)
}-*/;
This method works, but there's a lot of boilerplate involved. Once I
get a decent milestone to satisfy me, I'm going to try writing a
generator for this to make the static accessor functions, because as
it is, I've basically got to write the same code three times for each
function; once to do it, once to translate through JS, and another for
static accessor functions.
I'm telling you right now, unless you HAVE to use FRAMEs or an
existing API, you are wasting your time and the efficiency of your
code trying to compile multiple modules to communicate with each
other. It's possible, but it's gross and now that runAsync is fully
Appengine compatible, your best best is to do everything in a single
module, and just build each frame as a "virtual frame", using two
runAsync() methods that build their elements using RootPanel.get
("id1") and RootPanel.get("id2") to put each module's implementation
into two divs that look and act like frames, but run in the same
environment. To do this, you actually want THREE modules. The root
module is what loads and builds the other two, plus it should access
the common interfaces and any common static functions so that the two
child modules don't have to include the code. Then you can do
GWT.runAsync(EntryPoint1.class, new RunAsyncCallback(){
public void onFailure();
public void onSuccess(){
GWT.<EntryPoint1>create(EntryPoint1.class).onModuleLoad();
}
});
http://code.google.com/p/xbook {source check out, look in the main src
folder, ai.yx.common.client.* }
This way, you can skip JSNI bridges, and just do regular java stuff
with static functions in common code area. This reminds me, when you
want to include common code to multiple modules, you put it into a
separate client package and add a dummy .gwt.xml module definition
that does NOT use an entry point. Think of module xml's like global
dependency / import maps. You've got to import all your code properly
in java, but you've got to tell GWT exactly what packages you want to
access from which other packages, AND in what order to load them.
It's basically an extended classpath that GWT uses to trim deprecated
packages by only including what you need. To make a common import
package, just put it in it's own client package, with a .gwt.xml in
the /client root folder that just <inherits /> whatever dependencies
your common interfaces / static functions need, with NO NEED FOR AN
ENTRY POINT. If you inspect some PRETTY compiled outputs, Entry
points are added, in the inheritance order used, in the module's main
onModuleLoad; an object of each EntryPoint is created and it's non-
static onModuleLoad is called to give your app static access to a
singleton, instance-level object of each EntryPoint.
Interfaces and static functions shouldn't need EntryPoints, but if
they do, you can include them. If you want, for reference, you can
check my pre-release code {currently a terrible mess} at
http://code.google.com/p/xbook. I basically just svn import'd my
project split in two so I could use prerelease gwt2.0 to build widgets
in OOPHM and another for Appengine support. Once I get back to my
main dev box, I'll restructure my code into a single project and make
it must easier to implement, possibly with a jar for quick reference.
If you still want to use JSNI across frames, tell me why, and I can
probably save you some time figuring out how to specifically hack it
out. If I have any code you can hack on, I can extract it so it's not
so terribly confusing as my current code hive.
Short answers:
1) Use seperate gwt modules {preferable without EntryPoints} for
client code; extracting it and it's base dependencies in one
package.
2)If you want two FRAMES to communicate, they need to exist as
children of a common root Module that hooks their Rx(JSO x) <--> JSO Tx
() functions up in JSNI. If you want two IFRAMES to communicate, you
just need to designate one as parent and the other as child. Then,
before making the child iframe, have the parent put a global,
namespaced function for it's child to callback on into the $wnd
variable, create the child frame, on child load, call $wnd.parent
['nsCallback'].hookup($wnd, this) so both scopes store direct
references to each other's Rx and Tx methods, then start sending JSOs
across!
G'Luck!