
Hi Mark, sorry for late response. I've looked at GWTP -> UberFire migration presentation, looks interesting. It will be best if we discuss everything next week, I'll schedule a meeting on Monday (Nov 10) and also share it on devel-list for anyone interested to participate. @other, if you're interested in GWT, GWT-Platform, GIN, Errai, CDI, UberFire or JavaScript in general, please join this session. Some inline comments below. Regards, Vojtech ----- Original Message -----
From: "Mark Proctor" <mdproctor@gmail.com> To: "Alon Bar-Lev" <alonbl@redhat.com> Cc: "Vojtech Szocs" <vszocs@redhat.com>, devel@ovirt.org Sent: Wednesday, November 5, 2014 5:06:24 PM Subject: Re: [ovirt-devel] Thoughts on modularization
Not sure if my previous email made it to the wider level@ovirt.org list. I just subscribed :) So I’ll repeat the info.
Here is a migration path, with detailed explanation on GWTP mappings: https://docs.google.com/presentation/d/1KImrCvvqaUTgULP-CksUfGwLchJv4uB-dKQS... <https://docs.google.com/presentation/d/1KImrCvvqaUTgULP-CksUfGwLchJv4uB-dKQSgHPX6rU/edit#slide=id.p14>
Here presentation I gave yesterday, showing all the work we’ve done in BRMS and BPMS and doing. http://blog.athico.com/2014/11/red-hat-jboss-brms-and-bpms-workbench.html <http://blog.athico.com/2014/11/red-hat-jboss-brms-and-bpms-workbench.html>
It also shows a little around our Screens and Perspective plugins, or two units of extensions. Both of which have polyglot bindings (GWTExported, will migrate to @JsType later). Implicitly Maven is our unit of modularity, with maven dependency tree to declare this - however this is not recognised in any internal registry. CDI just scans and picks up any @Screen, @Perspective etc. But could be added, to give physical representation of that unit of modality, with life cycle callbacks - we just haven’t had a need for this yet.
For us, I'd like to have modularity implemented in a way to avoid "the big GWT app compilation" step. Doesn't matter if we ultimately go for "pure modular" approach or "core that invokes modules" approach, the big goal for us is to split frontend build into several projects. Maven as unit of modularity is cool but only for compile-time-known projects. I'd like to try a different approach, as you wrote - give them some physical representation and load them at runtime.
Our plan over 2015 is to use JsType to create a contract for all the things a module needs. We will then compile modules separately against this, with iframe separation, so each Module is loaded as a separate GWT app. This does mean GWT core repetition, a pita, but that atleast gets us started and may be solvable by a custom GWT linker.
Actually, this iframe approach is what we took in oVirt UI plugins! :) So I see that you're approaching modules from GWT perspective, sounds interesting. However, there are already existing JS frameworks and tools that solve modularization (but they come from JS perspective), like RequireJS (AMD) or ES6's module spec. Assuming JS is here to stay as the dominant web UI technology, I'd rather utilize existing ES6 modules than implementing some GWT-specific module system on my own. But let's discuss that in detail next week.
Longer term we’d like to work with GWT team. They now use the Closure compiler, this support symbol tables, and I expect how their incremental compiler works for their super dev mode. We want to achieve two things 1) stop recompilation of maven modules, when aggregated into sub projects. 2) declare apis that cannot be pruned 3) export a symbol table to allow later compilation of runtime extensions against those, without requiring a repetition of the GWT core (i.e. problem with our first attempt).
Very interesting stuff! :)
We will still continue with our polyglot bindings approach, such as with the AngularJS stuff we have done. But I do not see this as the ideal programming model - it hides much of what Errai brings, around event bus, and general java refactoring capabilities. However it is still useful for our customers, who want to write extensions, but do not want to touch or learn GWT.
If we take modular approach, nothing prevents us to implement "root" module in UberFire/Errai and expose high-level API for sub-modules to consume. Sure, GWT/Java brings advantages of Java statically typed language and its development/build tools, I agree. The concept of event bus is also good as it allows decoupling of application components. For me, learning lessons from oVirt UI plugins, I'd rather avoid the "have core app as runtime monolith and just expose some JS API for small extensions customers can do" scenario. I'd rather treat both core and 3rd party modules/extensions on the same level.
Mark
On 5 Nov 2014, at 15:32, Alon Bar-Lev <alonbl@redhat.com> wrote:
----- Original Message -----
From: "Vojtech Szocs" <vszocs@redhat.com> To: "Alon Bar-Lev" <alonbl@redhat.com> Cc: devel@ovirt.org, "Mark Proctor" <mdproctor@gmail.com> Sent: Wednesday, November 5, 2014 5:24:14 PM Subject: Re: [ovirt-devel] Thoughts on modularization
----- Original Message -----
From: "Alon Bar-Lev" <alonbl@redhat.com> To: "Vojtech Szocs" <vszocs@redhat.com> Cc: devel@ovirt.org, "Mark Proctor" <mdproctor@gmail.com> Sent: Wednesday, November 5, 2014 4:12:06 PM Subject: Re: [ovirt-devel] Thoughts on modularization
----- Original Message -----
From: "Vojtech Szocs" <vszocs@redhat.com> To: devel@ovirt.org Cc: "Mark Proctor" <mdproctor@gmail.com> Sent: Wednesday, November 5, 2014 5:04:24 PM Subject: [ovirt-devel] Thoughts on modularization
Hi guys,
I've discussed this recently with Yair and Mark, I just wanted to share some more thoughts on this topic -- in particular, how modularization problem can be approached (regardless of implementation details).
I see two approaches here. The typical one is to define APIs for modules to consume. For example, oVirt Engine extension API has API for auth stuff; oVirt UI plugin API has API for showing tabs and dialogs, etc. The advantage is strict consistency, disadvantage is burden of having to maintain the whole API. With this approach, you tell modules: "This is the API to work with system, defining how you can plug into it."
Now turn 180 degrees. The other approach, which is really interesting, is to let modules themselves export API. This naturally leads to module hierarchies. Ultimately, this leads to micro-kernel-style development, where all logic resides in modules. Now you might ask: "What if we want to employ some consistent work flow across multiple modules? For example, have some pluggable *auth* infra?" -- this can be done via some "higher" level module, that exports API and "lower" level modules consume that API.
If you have any ideas, please share!
Both solutions can be applied using existing extension api, an extension can locate other extension and interact with it the same way the core interacts with extensions.
But how does core interact with extensions? I assume via well-defined API, i.e. in accordance with first approach mentioned above.
presentation: http://www.ovirt.org/File:Ovirt_3.5_-_aaa.pdf <http://www.ovirt.org/File:Ovirt_3.5_-_aaa.pdf>
package org.ovirt.engine.api.extensions;
/** * Interface of an extension. */ public interface Extension {
/** * Invoke operation. * @param input input parameters. * @param output output parameters. * * <p> * Interaction is done via the parameters. * Exceptions are not allowed. * </p> * <p> * Basic mappings available at {@link Base}. * </p> * * @see Base */ void invoke(ExtMap input, ExtMap output);
}
With second approach mentioned above, core would not interact with extensions at all (or in a very limited way), instead - extensions would interact with each other. In other words, extension would not need to implement core-specific API (there would be none), instead it would inject its dependencies (other modules/extensions) and consume their APIs. This is the difference I wanted to point out :)
The extension interface is primitive to enable exactly that, provided java people will open their minds :)
Regards, Alon