Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Split UI Across Multiple Maven Modules
I've been learning up on Maven by building on the
vaadin-archetype-application-example archetype (v7.5.0). That archetype works well at present, but I've noticed that there is only one module for the UI (excluding the widgetset).
This is fine right now, but is this the recommended approach for a large application with potentially hundreds of views? I think it would be better to break the UI down into logical sub-modules (for example, have a ui-parent module with login-ui and crud-ui submodules). This is where I'm stuck. The production module generated by the archetype does some magic (war overlays and resource unpacking) that requires a single UI war file, so I can't really split it out nicely.
Is the recommended approach just to suck it up and keep my UI in a single module, or do people decompose the UI and then use something like shade or assembly to build up a war file?
You should definitely split your project into multiple modules. I've seen projects where there is an assembly module that then does a composition of everything that is needed. I recall Petter Holmström writing a blog post about making an "OSGi like" multimodule maven project which allows you to dynamically register views. Unfortunately, I can't find the blog post, but I did find the source code, which may be of some help to you.
I've done a simplified approach in one of my hobby projects. Really simple to do, but doesn't give you much flexibility nor is it done "the proper way". What I've done, is simply have one WAR module which contains my UI class. I've split my views into different modules, but those are packaged as JARs. Then my module that is packaged as a WAR depends on the view JARs. Works just fine for me, but I don't use overlays, assemblies or profiles.
Hi Kim, thanks for taking the time to reply.
The OSGi-esque project looks quite interesting, but I've thought about the structure some more and I've arrived at a solution that I'm happy with. I've created two basic module graphs to show how I've changed the structure.
Old Module Structure:
This graph depicts the structure of the Vaadin archetype application:
I found a few problems with this structure:
- The war file is produced out of the UI module. This doesn't seem like a logical place to produce an artifact that encompasses the entire application.
- The UI module cannot have submodules as it produces a war file, so you're stuck with a very flat module structure or a bloated UI module.
- The widgetset is compiled twice for production: once in Widgetset, and again in the Production module if the production profile is enabled.
- A lot of complex maven goals are required to make this work (as alluded to in my original post).
New Module Structure:
So, my new module structure looks more like this:
The UI and backend parent modules are just plain old parent Maven modules that have some common dependencies for the children to take advantage of.
The widgetset module is largely unchanged, but I changed the GWT compilation parameters to produce a production build (I could easily add a profile to tweak these). This means there's no need to compile the widgetset and then recompile it for production, yielding a significant reduction in compilation time.
The most important change, however, is the bootstrap module. This module contains only a few classes, including:
- The UI class
- The UI servlet
- My dependency injection setup code (using Guice)
- The webapp contents that were previously in the UI
The war file is produced out of the bootstrap module, which removes complexity from the other modules. I feel like this is a more appropriate location from which to produce an application war file than the UI module.
For learning purposes, I'm slowly transforming the archetype app into a basic issue tracker. I've started by implementing a basic JPA backend to the original app, and I now plan to start implementing a basic issue tracker UI. I've put it on Github: https://github.com/chrisparton1991/tracker