Using "self-contained" approach to package Vaadin portlets

As you might know, Vaadin libraries are bundled in Liferay. This makes it easy to start developing basic Vaadin portlets and you’ll also save in war file size as you are sharing the libraries between your projects. There are also a couple of global Liferay configuration properties (like vaadin.theme) that affect all Vaadin projects deployed on Liferay.

The approach currently used by most tools has some inconveniences though. Practically all your portlet projecs have to use same version of Vaadin and share the set of Vaadin add-ons. When you update one Vaadin portlet, all others should follow.

As a new default way of packaging your Vaadin portlets, you should start using a “self-contained” approach instead. We discussed this yesterday in our joint webinar by James Falkner and Mac Przepióra. In this packaging style each project has its own Vaadin libraries and generated resources packaged into its war file. In addition, each project can configure itself independently of to another and of the global configuration in portal.properties. Now adding add-ons to a project is as easy as in servlet based Vaadin apps and there is a new Vaadin version available, all projects don’t need to be updated at once.

As a downside, the war file size grows a bit and a page with multiple Vaadin portlets from different projects might become slightly slower to load. In case you have lots of small Vaadin portlets, from different portlet projects, and it is essential to optimize the page well, then, and only then, I can still suggest to use the shared library packaging.

The new packaging style is available as a Maven archetype. To prepare for using Liferay IDE with Maven, you’ll need to add a “liferay” profile to your settings.xml For more information about using Maven with Liferay IDE, you can refer to Liferay documentation.

This is the profile I have in mine:

<profiles>        <profile>            <id>liferay</id>            <properties>                <liferayinstall>/Users/youraccount/Applications/liferay-portal-6.2-ce-ga2</liferayinstall>                <plugin.type>portlet</plugin.type>                <liferay.version>6.2.1</liferay.version>                <liferay.maven.plugin.version>6.2.1</liferay.maven.plugin.version>                <liferay.auto.deploy.dir>${liferayinstall}/deploy</liferay.auto.deploy.dir>                <liferay.app.server.deploy.dir>${liferayinstall}/tomcat-7.0.42/webapps</liferay.app.server.deploy.dir>                <liferay.app.server.lib.global.dir>${liferayinstall}/tomcat-7.0.42/lib/ext</liferay.app.server.lib.global.dir>                <liferay.app.server.portal.dir>${liferayinstall}/tomcat-7.0.42/webapps/ROOT</liferay.app.server.portal.dir>            </properties>             </profile>    </profiles> 

 

The archetype can be found from Maven central with groupId com.vaadin and artifactId vaadin-archetype-liferay-portlet. If you create a project with Eclipse and Liferay IDE, the next step is to configure the project using the previously discussed profile via project properties. Screenshot below shows where to do that.

After that the project should compile fine and Liferay IDE will recognize the project as a Liferay project (so you can also use Liferay Maven plugin goals like liferay:deploy and can edit Liferay deployment files like liferay-plugin-package.properties using Liferay IDE’s graphical forms-based editors).

Relevant Maven build targets:

install will package the project as war under target directory. If a widgetset has changed, this also activates the GWT compiler to build a new widgetset, so it might take a minute or two. E.g. if you add an add-on, like Vaadin Charts, execute this goal after modifying your pom.xml.

liferay:deploy will deploy the war to the liferay instance defined in your settings.xml

clean removes all generated resources like class files and widgetsets.

In case you wish to activate liferay:deploy during install target, you might also wish to configure liferay-maven-plugin with the following configuration.

<executions>
    <execution>
        <goals>
            <goal>deploy</goal>
        </goals>
        <phase>install</phase>
    </execution>
</executions>

We’ll most likely change the non-Maven builds to guide towards this kind of packaging style in the near future. Until then, and in case for some reason you cannot start to use Maven builds for your projects, you can create a one project stub using the archetype and then adapt that for your ANT build. I haven’t tried it but I think it should work as well.

The good thing about Maven builds is that it hints your IDE how it should configure the project. If your colleague is a big fan of some other IDE, he can probably just open the project in his IDE and start working. I tested this with NetBeans and it worked flawlessly, and I’d be surprised if it didn’t work in IntelliJ IDEA as well.

Migrating to Vaadin 7

In this post we assume you are using Vaadin 7, but the latest version of Liferay (6.2) includes an older version of Vaadin (Vaadin 6). This isn’t a problem if you use the new vaadin-archetype-liferay-portlet and per-project approach as outlined above. However, if you have many projects that use Vaadin and are looking to optimize your production environment (to minimize the duplication of runtime classes and widgetsets between projects and tosave on JVM resources), you may want to use a single version of Vaadin across all projects (the “global” approach), which requires upgrading the bundled version of Vaadin (6.8) to whatever version you wish to use.

In addition, we are working with Liferay to update the Liferay IDE plugin to support not only creating new Vaadin 7 projects. In the future, new projects should be created in a form of “self-contained” strategy by default, whether they used Maven or not.

Blogs
BTW. If you have only one liferay setup on you development machine, you can also activate the liferay profile by default:
<activeProfiles>
<activeProfile>liferay</activeProfile>
</activeProfiles>

Then you don't need to explicitly enable it per project in you IDE.
So what is involved w/ switching from "self-contained" to "shared"?

Clearly in a production environment with a lot of Vaadin portlets you're going to want to be in shared mode, but if you've created your portlets in "self-contained" mode you'll want to switch them to shared...

Worst thing I can think of is a page w/ V7 portlets on it, one running 7.1.1, another running 7.1.2, another running 7.1.3, another running 7.1.4, ...

The idea of "self-contained" may seem appealing from a management perspective, but the runtime implications of all of these different versions floating around to me would be a nightmare.
Server is using different class loader for different portlets, so only problem at runtime is that there are n+1 classes loaded by the JVM, so there is just slightly more memory used. I wouldn't be concerned about that until it is a problem. In most cases actual sessions consume more memory than loaded class implementations.

I'd guess the "nightmare" might start earlier on client side, in case you have multiple different Vaadin portlets, from different war files, visible on the same page. Each new Vaadin app, adds its own widget set -> the amount of loaded JS files grows linearly.
Server side is not my concern. Even four V6 portlets end up w/ four copies of the classes loaded.

But it's totally the client side browser impact that is my concern. At least when all 4 are using the same version, the theme, js, and the engine are only loaded once...

That's why, for my production system, I'd rather switch out of 'self contained' mode and roll back to the single system Vaadin + control panel, just so I can limit the impact on the browser side.
David could you help me with this issue please
https://www.liferay.com/es/community/forums/-/message_boards/message/38439950
Agreed, we'll definitely need to cover some best practices for this in upcoming articles.

In one don't want to use the Vaadin control panel, one way would be to use a shared "my-company-vaadin-dependencies" project that would define used Vaadin version, possible add-ons and build the shared widget set to be placed into portal wide /html/ directory like to day. Then individual portlet projects would just depend to this project and use the shared widget set like before.
Hi Matti, I like the idea about self-contained approach, however I'm more concerned about scenario - I have old portal applications deployed on LR 6.2 having vaadin 6.8 as "global" way along with "custom-widget" and "custom-theme" now, I want to develop new portal having "vaadin 7" and "new-portal-specific-widget" and "newer-style" in "self-contained" mode. Is it possible to run both "newer-vaadin7" portal and "old-vaadin" portal on same page?
It works perfectly that you have both versions within same portals that way, but there might be some issues with "theme leaking". I haven't tested it, but I'd bet with Valo in Vaadin 7 portlet you should be doing just fine though.
Typically, though, in portlet development you complete one and move on, you don't go back to it unless there is some sort of defect to be resolved.

So I believe, over time, you would end up w/ a portlet at 7.0.5 (latest when it was released), one at 7.1.7, one at 7.2.2, one at 7.3.1, ... Without the shared vaadin concept, I think over time your portal can get polluted with many different Vaadin versions, not just the global 6.8 and others at self contained yet different versions of Vaadin 7.

That's the part that I don't believe has been addressed - what is the impact of multiple Vaadin versions on the server and in the browser...
Ya, I agree that moving ahead with "self-contained" approach when you have multiple portal applications is not good. But to start with migration towards newer Vaadin version of single portal application you can easily do and test it with "self-contained" way.

My original problem is : I have LR 6.2 with multiple portal applications using existing configured theme, widgets and vaadin 6.8 in "global" way. Now, I started porting/migrating one of the portal application with Vaadin 7 + newer widget + newer theme in "self-contained-way" but, it is not working and failing due to failure in loading widgets/theme.
So, I want to know whether such thing works and tried by any one? If yes, please guide/hint it.
That's a different issue altogether. If you can move the issue over to the forum, it's probably a better place to solve it than here. Be sure to include "Vaadin" in the subject line and I'll chime in...