How to split a gwt-platform 1.x in more than a project?

70 views
Skip to first unread message

Vicente J. Ruiz Jurado

unread,
Dec 10, 2014, 2:53:42 PM12/10/14
to gwt-pl...@googlegroups.com
Hi there:

Yesterday I asked this in SO:
https://stackoverflow.com/questions/27386521/split-a-gwt-platform-1-x-application-on-more-than-one-project

because we are trying to find a way to split our gwt application in a similar way we did in 0.7. We did something similar to:
https://stackoverflow.com/questions/6409811/split-a-gwt-platform-application-on-more-than-one-project

Any recommendation?

TIA,

Richard Wallis

unread,
Dec 10, 2014, 10:41:56 PM12/10/14
to gwt-pl...@googlegroups.com
Will you compile both projects together into one at the end or are you talking about two completely separate gwt projects that need to interact together?

--
You received this message because you are subscribed to the Google Groups "GWTP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gwt-platform...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Vicente J. Ruiz Jurado

unread,
Dec 11, 2014, 11:30:53 AM12/11/14
to gwt-pl...@googlegroups.com


El jueves, 11 de diciembre de 2014 04:41:56 UTC+1, Richard Wallis escribió:
Will you compile both projects together into one at the end or are you talking about two completely separate gwt projects that need to interact together?


Two different compilations (we use maven with different profiles pointing to different .gwt.xml). Using 0.7:
https://gitorious.org/kune/trunk/source/fbbd969d81d1244c9d09e1f6226f831f94511c72:src/main/java/cc/kune/Kune.gwt.xml
and
https://gitorious.org/kune/trunk/source/fbbd969d81d1244c9d09e1f6226f831f94511c72:src/main/java/cc/kune/KuneEmbed.gwt.xml

now in 1.x  I was trying to use two diferent bootstraps and modules in the .gwt.xml but the generated injectors are trying to use the wrong presenters.

TIA,

Richard Wallis

unread,
Dec 11, 2014, 11:29:41 PM12/11/14
to gwt-pl...@googlegroups.com
Ok I'm not fully following. Is only one *.nocache.js file being injected into the host page at the end?

One thing to look out for is the GWTP generators will search out and try to build proxies for any Presenter's that are in the gwt source path.  So if some Presenter's are not used by one of your gwt modules you need to put them on a source path that the module can't see using the <source path=""> tag in your gwt.xml file.

Vicente J. Ruiz Jurado

unread,
Dec 12, 2014, 4:04:38 AM12/12/14
to gwt-pl...@googlegroups.com


El viernes, 12 de diciembre de 2014 05:29:41 UTC+1, Richard Wallis escribió:
Ok I'm not fully following. Is only one *.nocache.js file being injected into the host page at the end?

No, there are several. This app (and other gwt apps I'm participating in) have several EntryPoints. For instance you can build the complete App, or another for embed in other webpages (that uses a subset of presenters), or another one with only shows a small part of the app for development purposes, etc.

Imagine that in gwtp 1.X you have several ways to bootstrap your app. Each boostrap process at the end use a subset of presenters (some shared, some only used in this app/bootstrap process) and the compilation have different sizes (and boot time).


One thing to look out for is the GWTP generators will search out and try to build proxies for any Presenter's that are in the gwt source path.  So if some Presenter's are not used by one of your gwt modules you need to put them on a source path that the module can't see using the <source path=""> tag in your gwt.xml file.

This is our problem (typical error):

Unable to create or inherit binding: No @Inject or default constructor found for cc.kune.gspace.client.viewers.EmbedPresenter$EmbedView


because we don't use this presenter in the boot process of that part of the app.

Why gwtp doesn't build only the proxies of the presenters that you bind in the modules that you are declaring with the "gin.ginjector.modules" configuration property?

So for instance here:

  <inherits name='com.gwtplatform.dispatch.Dispatch' />
 
<inherits name='com.gwtplatform.mvp.MvpWithEntryPoint' />

 
<set-configuration-property name="gin.ginjector.modules"
   
value="cc.kune.core.client.CoreGinModule" />
(...)
 
<extend-configuration-property name="gin.ginjector.modules"
   
value="cc.kune.docs.client.DocsGinModule" />
 
<extend-configuration-property name="gin.ginjector.modules"
   
value="cc.kune.events.client.EventsGinModule" />
(...)
 
<set-configuration-property name="gwtp.prebootstrapper"
   
value="cc.kune.client.KunePreBootstrapper" />
 
<set-configuration-property name="gwtp.bootstrapper"
   
value="cc.kune.client.KuneBootstrapper" />


you only use the presented binded in that modules, and in other gwt.xml:

  <inherits name='com.gwtplatform.dispatch.Dispatch' />
 
<inherits name='com.gwtplatform.mvp.MvpWithEntryPoint' />

 
<set-configuration-property name="gin.ginjector.modules"
   
value="cc.kune.core.client.CoreGinModule" />
 
<extend-configuration-property name="gin.ginjector.modules"
   
value="cc.kune.wave.client.EmbedCoreGinModule" />
(...)
 
<set-configuration-property name="gwtp.prebootstrapper"
   
value="cc.kune.client.KunePreBootstrapper" />

 
<set-configuration-property name="gwtp.bootstrapper"
   
value="cc.kune.client.KuneEmbedBootstrapper" />


only uses other subset of presenters.

Richard Wallis

unread,
Dec 12, 2014, 4:15:42 AM12/12/14
to gwt-pl...@googlegroups.com
Agree it would be nice if GWTP would detect only the Presenters that are bound.

But it is an extremely complex problem to solve.

For now, if you are not using a Presenter in a gwt module then it must not be under the package set by <source path="com.example.client">.

--

Vicente J. Ruiz Jurado

unread,
Dec 12, 2014, 5:54:30 AM12/12/14
to gwt-pl...@googlegroups.com


El viernes, 12 de diciembre de 2014 10:15:42 UTC+1, Richard Wallis escribió:
Agree it would be nice if GWTP would detect only the Presenters that are bound.

But it is an extremely complex problem to solve.

For now, if you are not using a Presenter in a gwt module then it must not be under the package set by <source path="com.example.client">.


And, it's a recommended way to use your custom ginjetors without presenters detection and avoid the auto injector?

Thanks,

Richard Wallis

unread,
Dec 12, 2014, 6:06:31 AM12/12/14
to gwt-pl...@googlegroups.com
No, using a custom ginjector will not solve your problem.

The problem is that the GWTP generators search your source directory for Presenters that have Proxy interfaces annotated with @ProxyStandard, @ProxyCodeSplit etc.  It then generates Proxy classes for all those Presenters.

The generated Proxy classes need to be able to instantiate their matching Presenters and Views, which is why there is an error if those classes are not bound.

The only way to solve the problem is to move the Presenters you're not using out of the GWT source path so that GWTP does not create proxies for them.

--

Vicente J. Ruiz Jurado

unread,
Dec 12, 2014, 11:59:26 AM12/12/14
to gwt-pl...@googlegroups.com
Let's make the same question in another way.

Imagine that I want some app with two views... one for some type of browsers, or web pages, or devices, and another view, totally different (but with some shared code) for other scenario.

These views share a lot of code, but the compiled result are totally different.

Do we need to use two different gwt projects for that in gwtp 1.x?

Or the same question in another way: How to build several different boot process in a project that use gwtp 1.x?

PS: I participate in different gwt projects with 4 EntryPoint, 2 EntryPoints and another with 5 different EntryPoints (doing a fast grep -r).

Christian Goudreau

unread,
Dec 13, 2014, 1:36:45 PM12/13/14
to gwt-pl...@googlegroups.com
There's actually a lot of ways to accomplish the same thing as you're trying to achieve. Personally, I've achieved into large project similar result with only one entry point.

As Richard stated, if you have two entry point, two ginjectors under the same classpath, GWTP will find all Proxies even if they are unrelated.

For form factors, GWTP already ships with a way to bind different formfactor depending on formfactor detection. You can enhance this to go even further (I've build a facebook-desktop-mobile) web application using the same technique.

Carstore showcase how to bind different gin modules depending on the default three formfactors that you can define:

FYI, pre 1.+ binding should still work within 1.+, all generators added within 1.+ generated boiler plate code that you had to write before to configure.

Christian Goudreau | CEO - Président

--

Vicente J. Ruiz Jurado

unread,
Dec 14, 2014, 5:42:55 AM12/14/14
to gwt-pl...@googlegroups.com
We don't want only one entry point (GWT has many different usages) but thanks for your answers and samples.

Vicente

Christian Goudreau

unread,
Dec 15, 2014, 7:44:16 AM12/15/14
to gwt-pl...@googlegroups.com
No worries :D It would only help to know the use case.

For example, I've seen a lot of people using multiple entry points for and administration section of there apps. The main reason was because they wanted to reduce the Javascript file size. My answer to that case is that in fact, you're increasing the cumulative file size by doing it (shared code being compiled twice).

To do the same thing, I use provider bundles. My admin section will then be code splitted and shared code compiled only once.

Your use cases really interest me, because I want to know how we can help to make it easier and more performant for users that share the same interests :D

Christian Goudreau | CEO - Président

Vicente J. Ruiz Jurado

unread,
Dec 18, 2014, 2:53:31 AM12/18/14
to gwt-pl...@googlegroups.com


El lunes, 15 de diciembre de 2014 13:44:16 UTC+1, Christian Goudreau escribió:
 
Your use cases really interest me, because I want to know how we can help to make it easier and more performant for users that share the same interests :D

Some use cases if this help:
  • Some big gwt app (several 100k lines of code) and we want to develop only a part of the code so we want fast compilations for this part of the code and for only one user.agent, etc.
  • We have some injector/modules with mocks for some parts of the code.
  • Some big app that are multipurpose, so users can build, configure and adapt different apps depending of its necessities (each app sample has a different EntryPoint, dependencies, etc).

Vicente

Richard Wallis

unread,
Dec 18, 2014, 3:35:57 AM12/18/14
to gwt-pl...@googlegroups.com
Hi Vincent

Splitting up a big gwt app in multiple projects won't make the compile faster because the gwt compiler has to compile from java source to javascript.  In normal java when you have a jar on your classpath the jar won't need to be recompiled but with GWT it always has to be.  This is why gwt jars have to include their source.

And with incremental compile, even for a very large project recompiles should take less than a second.

Depending on how you manage your dependencies splitting up your gwt project can force more frequent full compiles. Because changing a source file in a dependency won't be picked up by the incremental compiler.

--

Christian Goudreau

unread,
Dec 18, 2014, 10:21:55 AM12/18/14
to gwt-pl...@googlegroups.com
  • Some big gwt app (several 100k lines of code) and we want to develop only a part of the code so we want fast compilations for this part of the code and for only one user.agent, etc.
Gotcha, yes that single entry point will compile faster, but it will increase the download size of each pieces as they will include each time the shared code.

  • We have some injector/modules with mocks for some parts of the code.
I use maven profiles with different .gwt.xml to achieve that. (dev, staging, qa, prod)

  • Some big app that are multipurpose, so users can build, configure and adapt different apps depending of its necessities (each app sample has a different EntryPoint, dependencies, etc).
I do that as well, I add one line in my aggregator gwt.xml and it adds a whole module to the system.

That being said, I also have to support really soon "drop-in" modules which will have different entry points and use a JS API (done through JS interop) to register itself to the core system. So I can understand why you would need multiple entry point.

Honestly, to really help you, community support isn't enough, we would need to see the code and debug. I suggest you to contact me personally for support if you're interested :D I'll also be able to show you our architecture that allows flexible output for big apps.

Cheers,

Christian Goudreau | CEO - Président

Reply all
Reply to author
Forward
0 new messages